Ir al contenido

Manual para crear tu propia invitación — Madify Invita

Este documento explica cómo armar tu propia página de invitación (a mano o pidiéndosela a una inteligencia artificial como Claude) para publicarla en Madify Invita. Tu página recibe los datos de tu evento automáticamente y las confirmaciones de asistencia llegan a tu panel.

Si vas a usar una IA: copia este documento completo en la conversación y pídele tu diseño. Al final hay un bloque «Prompt para la IA» listo para usar.

1. Qué vas a entregar

Un archivo ZIP con tu sitio:

mi-invitacion.zip
├── index.html        ← obligatorio (en la raíz del ZIP o dentro de UNA carpeta)
├── css/estilos.css
├── js/app.js
└── img/foto.webp
  • index.html es la portada. Puedes tener más páginas (galeria.html); también reciben los datos.
  • Usa rutas relativas: img/foto.webp, nunca /img/foto.webp ni rutas de tu computadora.
  • Todo en UTF-8.

2. Reglas del ZIP

  • Extensiones permitidas: avif, css, eot, gif, htm, html, ico, jpeg, jpg, js, json, m4a, map, mjs, mp3, mp4, ogg, otf, png, svg, ttf, txt, wav, webm, webmanifest, webp, woff, woff2.
  • Máximo 50 MB comprimido, 200 MB descomprimido y 500 archivos.
  • Se ignoran __MACOSX/, .DS_Store y archivos ocultos. No se aceptan enlaces simbólicos ni rutas con ...
  • Optimiza las imágenes (WebP o JPEG, menos de 400 KB cada una): la mayoría de tus invitados abrirá la invitación desde el celular.
  • Si la página tiene un error de sintaxis en las variables, el sistema te dice el archivo y la línea.

3. Datos dinámicos (variables)

Tu HTML se procesa con el motor de plantillas de Django. Escribe {{ variable }} donde quieras que aparezca un dato y {% if … %}…{% endif %} para mostrar algo solo si existe.

Llaves principales:

Variable Qué es
event Datos del evento (tabla «event»)
guest El invitado del link personal, o vacío en el link general (tabla «guest»)
rsvp La respuesta previa de ese invitado, o vacío (tabla «rsvp»)
rsvp_config Configuración del formulario de confirmación (tabla «rsvp_config»)
theme Solo en diseños del catálogo: las opciones que personaliza el cliente ({{ theme.<clave> }}) y theme.design (slug, name, version). Vacío en un ZIP propio
now Fecha y hora actual del servidor

event

Variable Tipo Descripción Ejemplo
event.title texto Título del evento Boda de Ana y Luis
event.slug texto Path del evento en la URL boda-ana-y-luis
event.type texto Tipo (clave): boda, xv_anos, bautizo, primera_comunion, baby_shower, cumpleanos, fiesta, graduacion, corporativo, otro boda
event.type_label texto Tipo legible Boda
event.honorees texto Festejado(s) Ana y Luis
event.hosts texto Anfitriones / papás / padrinos Familia López
event.description texto Mensaje principal (usa linebreaksbr para saltos de línea)
event.starts_at fecha y hora Inicio del evento (usa el filtro date) {{ event.starts_at|date:"l j \d\e F" }} → sábado 24 de octubre
event.ends_at fecha y hora Fin del evento (puede estar vacío)
event.dress_code texto Código de vestimenta Formal
event.contact_phone texto WhatsApp del anfitrión (con lada) 5214431234567
event.whatsapp_url URL Link directo a WhatsApp del anfitrión (vacío si no hay teléfono) https://wa.me/5214431234567
event.rsvp_deadline fecha Fecha límite para confirmar (puede estar vacía) {{ event.rsvp_deadline|date:"j \d\e F" }}
event.rsvp_open sí/no Si todavía se puede confirmar True
event.allow_public_rsvp sí/no Si se puede confirmar sin link personal True
event.allow_children sí/no Si la invitación admite niños True
event.locations lista Ubicaciones en orden (ver tabla de ubicaciones) {% for loc in event.locations %}…{% endfor %}
event.main_location ubicación La primera ubicación (o vacío) {{ event.main_location.name }}
event.links lista Links del evento (ver tabla de links) {% for link in event.links %}…{% endfor %}
event.gift_links lista Solo los links de tipo «mesa de regalos» {{ event.gift_links.0.url }}
event.extra diccionario Datos libres que captura el anfitrión {{ event.extra.hashtag }}
event.url texto Ruta relativa de la invitación /boda-ana-y-luis/
event.public_url URL Dirección completa de la invitación (dominio propio si lo hay) https://invite.madify.mx/boda-ana-y-luis/

Cada ubicación (event.locations, event.main_location)

Variable Tipo Descripción Ejemplo
loc.kind texto Clave: ceremonia, recepcion, evento, otro ceremonia
loc.kind_label texto Tipo legible Ceremonia
loc.name texto Nombre del lugar (puede estar vacío) Parroquia de San José
loc.address texto Dirección Centro, Morelia
loc.maps_url URL Link de Google Maps tal cual lo capturaron (puede estar vacío) https://maps.app.goo.gl/…
loc.maps_link URL maps_url o, si está vacío, una búsqueda de Google Maps con lugar + dirección https://www.google.com/maps/search/?api=1&query=…
loc.starts_at fecha y hora Hora de esta ubicación (puede estar vacía) {{ loc.starts_at|time:"g:i a" }}
loc.notes texto Notas Estacionamiento en la parte trasera

Cada link (event.links, event.gift_links)

Variable Tipo Descripción Ejemplo
link.kind texto Clave: regalos, hospedaje, transmision, playlist, fotos, otro regalos
link.kind_label texto Tipo legible Mesa de regalos
link.label texto Texto del botón Ver mesa de regalos
link.url URL Destino https://mesaderegalos.liverpool.com.mx/…

guest (solo cuando se abre con link personal)

Variable Tipo Descripción Ejemplo
guest.name texto Nombre de la invitación (persona, pareja o familia) Familia Pérez
guest.max_adults número Lugares para adultos 2
guest.max_children número Lugares para niños 1
guest.max_total número Total de lugares 3
guest.token texto Código del link personal (?i=) VoVZx4P4BgNt

rsvp (la respuesta previa de ese invitado, si ya confirmó)

Variable Tipo Descripción Ejemplo
rsvp.name texto Nombre con el que confirmó Laura Pérez
rsvp.attending sí/no Si asiste True
rsvp.adults número Adultos confirmados 2
rsvp.children número Niños confirmados 1
rsvp.message texto Mensaje que dejó ¡Felicidades!
rsvp.attendees lista Acompañantes: name, type (adult/child), age {% for a in rsvp.attendees %}{{ a.name }}{% endfor %}
rsvp.updated_at fecha y hora Última actualización de su respuesta

rsvp_config

Variable Tipo Descripción Ejemplo
rsvp_config.endpoint URL A dónde se manda la confirmación (POST JSON) /api/v1/public/events/boda-ana-y-luis/rsvp/
rsvp_config.token texto Token del invitado (vacío en el link general)
rsvp_config.mode texto guest (link personal), public (link general), invite_only (solo con link personal) o closed (ya cerró) guest
rsvp_config.max_adults número Máximo de adultos que puede confirmar quien abre la página 2
rsvp_config.max_children número Máximo de niños 1
rsvp_config.allow_children sí/no Si puede confirmar niños True
rsvp_config.deadline texto Fecha límite ISO (o vacío) 2026-10-15

Filtros útiles

{{ event.starts_at|date:"l j \d\e F \d\e Y" }}   → sábado 24 de octubre de 2026
{{ event.starts_at|date:"g:i a" }}              → 1:00 p.m.
{{ event.starts_at|date:"c" }}                  → 2026-10-24T13:00:00-06:00 (para cuentas regresivas en JS)
{{ event.description|linebreaksbr }}            → respeta los saltos de línea
{{ event.honorees|upper }}                      → ANA Y LUIS
{{ guest.max_adults|pluralize:"es" }}           → «es» si es plural (lugar/lugares)
{{ event.extra.hashtag|default:"#AnayLuis" }}   → valor por defecto si está vacío

Ejemplos:

<h1>{{ event.honorees }}</h1>
<p>{{ event.starts_at|date:"l j \d\e F" }} · {{ event.starts_at|date:"g:i a" }}</p>

{% if guest %}
  <p>¡Hola, {{ guest.name }}! Reservamos {{ guest.max_adults }} lugar{{ guest.max_adults|pluralize:"es" }}.</p>
{% endif %}

{% for loc in event.locations %}
  <h3>{{ loc.kind_label }}: {{ loc.name }}</h3>
  <p>{{ loc.address }}</p>
  {% if loc.maps_link %}<a href="{{ loc.maps_link }}">Ver mapa</a>{% endif %}
{% endfor %}

{% for link in event.gift_links %}<a href="{{ link.url }}">{{ link.label }}</a>{% endfor %}

Si tu JavaScript usa llaves dobles (Vue, Handlebars, etc.), enciérralo en {% verbatim %}…{% endverbatim %} para que no se procese.

4. Confirmación de asistencia

Opción A — formulario listo

<section id="confirmar">
  {% rsvp_form %}
</section>
{% rsvp_script %}   {# antes de </body> #}

Genera un formulario completo (nombre, asiste sí/no, adultos, niños, nombres de acompañantes, mensaje) que puedes estilizar con CSS: .rsvp-form, .rsvp-field, .rsvp-submit, .rsvp-success, .rsvp-error.

Opción B — tu propio formulario

Pon data-rsvp en tu <form> y usa estos name en los campos:

Campo (name) Qué es
name Nombre de quien confirma (obligatorio en el link general)
attending Asiste: radio/select/checkbox con valores yes/no (también si/no, true/false)
adults Número de adultos
children Número de niños
guests Total de personas (alternativa a adults/children; se cuentan como adultos)
message Mensaje para los anfitriones
phone Teléfono (opcional)
email Correo (opcional)
website Campo trampa anti-spam: agrégalo oculto y déjalo vacío

Atributos que entiende el script:

Atributo Para qué
data-rsvp En el
: lo conecta con la API (el endpoint sale de {% rsvp_script %})
data-rsvp-attendees Contenedor donde se generan los campos de nombre por cada adulto/niño
data-rsvp-when-attending Visible solo si responde que sí asiste
data-rsvp-when-declined Visible solo si responde que no
data-rsvp-children Se oculta si la invitación no incluye niños
data-rsvp-success Mensaje de éxito (se muestra al confirmar)
data-rsvp-error Mensaje de error
data-rsvp-closed Visible si la confirmación ya cerró
data-rsvp-invite-only Visible si solo se acepta con link personal
data-success-yes / data-success-no En el : textos de agradecimiento personalizados
<form data-rsvp data-success-yes="¡Gracias! Nos vemos pronto." data-success-no="¡Te extrañaremos!">
  <input name="name" placeholder="Tu nombre" required>
  <label><input type="radio" name="attending" value="yes"> Sí asistiré</label>
  <label><input type="radio" name="attending" value="no"> No podré ir</label>
  <div data-rsvp-when-attending hidden>
    <input type="number" name="adults" min="1" value="1">
    <input type="number" name="children" min="0" value="0" data-rsvp-children>
    <div data-rsvp-attendees></div>
  </div>
  <textarea name="message"></textarea>
  <input type="text" name="website" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px">
  <button type="submit">Enviar</button>
  <p data-rsvp-success hidden></p>
  <p data-rsvp-error hidden></p>
</form>
{% rsvp_script %}
  • Con link personal (?i=…) el nombre se llena solo, se respetan los lugares del invitado y, si ya había confirmado, su respuesta aparece para modificarla.
  • Sin link personal (link general) se pide el nombre y se respetan los límites del evento.
  • Los límites se validan también en el servidor: no se puede confirmar de más aunque alguien modifique la página.

5. Página de ejemplo completa (mínima)

<!doctype html>
<html lang="es-MX">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{{ event.title }}</title>
  <link rel="stylesheet" href="css/estilos.css">
</head>
<body>
  <header>
    <p class="eyebrow">{{ event.type_label }}</p>
    <h1>{{ event.honorees }}</h1>
    <p>{{ event.starts_at|date:"l j \d\e F \d\e Y" }} · {{ event.starts_at|date:"g:i a" }}</p>
    {% if guest %}<p class="hola">¡Hola, {{ guest.name }}!</p>{% endif %}
  </header>

  {% if event.description %}<section><p>{{ event.description|linebreaksbr }}</p></section>{% endif %}

  <section>
    {% for loc in event.locations %}
      <article>
        <h2>{{ loc.kind_label }}</h2>
        {% if loc.name %}<h3>{{ loc.name }}</h3>{% endif %}
        <p>{{ loc.address }}{% if loc.starts_at %} · {{ loc.starts_at|time:"g:i a" }}{% endif %}</p>
        {% if loc.maps_link %}<a href="{{ loc.maps_link }}" target="_blank" rel="noopener">Cómo llegar</a>{% endif %}
      </article>
    {% endfor %}
  </section>

  {% if event.gift_links %}
  <section>
    <h2>Mesa de regalos</h2>
    {% for link in event.gift_links %}<a href="{{ link.url }}" target="_blank" rel="noopener">{{ link.label }}</a>{% endfor %}
  </section>
  {% endif %}

  <section id="confirmar">
    <h2>Confirma tu asistencia</h2>
    {% if event.rsvp_deadline %}<p>Antes del {{ event.rsvp_deadline|date:"j \d\e F" }}.</p>{% endif %}
    {% rsvp_form %}
  </section>

  {% rsvp_script %}
</body>
</html>

6. Prompt para la IA

Copia y pega esto después de este manual, cambiando lo que está entre corchetes:

Con base en el manual anterior, crea mi invitación digital para [tipo de evento: boda, XV años, bautizo…]
con estilo [describe: elegante, minimalista, floral, rústico, colores dorado y verde olivo…].

Requisitos:
- Entrégame el contenido de cada archivo y la estructura del ZIP (index.html en la raíz, css/, img/).
- Usa SOLO las variables del manual ({{ event.… }}, {{ guest.… }}); no escribas datos fijos de fecha, lugar o nombres.
- Incluye una sección de confirmación con {% rsvp_form %} (o un formulario data-rsvp) y {% rsvp_script %} antes de </body>.
- Diseño mobile first, que cargue rápido (sin frameworks pesados); fuentes de Google Fonts permitidas.
- No cargues scripts de terceros (salvo Google Fonts) ni envíes datos a otros servidores.
- Si usas JavaScript con llaves dobles, enciérralo en {% verbatim %}.
- Rutas relativas para imágenes y CSS. Indica qué imágenes debo agregar y de qué tamaño.
Secciones que quiero: [portada con nombres y fecha, cuenta regresiva, mensaje, ubicaciones con mapa, mesa de regalos, galería, confirmación…].

7. Antes de enviar (checklist)

  • [ ] index.html en la raíz del ZIP y rutas relativas.
  • [ ] Probaste la página abriéndola en el celular (los datos aparecen como {{ … }} hasta que se publica: es normal).
  • [ ] La sección de confirmación usa {% rsvp_form %} o un form data-rsvp y {% rsvp_script %}.
  • [ ] Imágenes optimizadas y el ZIP pesa menos de 50 MB.
  • [ ] Sin scripts externos ni formularios que manden datos a otros sitios.

8. Cómo enviarlo

  1. Entra a tu panel: https://invite-app.madify.mx/admin/ → Mi sitio → Enviar sitio.
  2. Elige tu evento y sube el ZIP. Si algo no cumple las reglas, verás el error al momento.
  3. Lo revisamos (normalmente en menos de 24 horas) y te avisamos por correo cuando esté publicado. Si necesita cambios, te decimos cuáles.

Necesitas un plan que incluya sitio propio. Consulta los planes en https://invite.madify.mx/precios/.

9. Qué no se permite

  • Scripts que capturen datos de tus invitados y los manden a otros servidores, o formularios que apunten a otros sitios.
  • Contenido ilegal, engañoso u ofensivo, o que use marcas o imágenes sin permiso.
  • Intentar leer archivos del servidor o romper el sistema (la página se rechaza).

¿Dudas? .