Saltar al contenido principal

Formato de plantillas

Para desarrolladores

Una plantilla del editor visual se guarda como un documento JSON: filas, columnas y módulos, cada uno con sus propiedades. Es el documento que la API de plantillas devuelve y recibe completo en config, y el que un asistente de IA lee y edita, conectado por MCP o con la plantilla copiada desde el editor.

La especificación de esta página es la misma que entrega la API, así que puede leerla aquí o pedirla desde su integración:

Para ver un documento completo real, GET /v1/template-catalog/{category}/{name} devuelve una plantilla de la biblioteca sin copiarla.

El recorrido completo por la API está en Plantillas por API, y los ejemplos de cada tipo de módulo en Ejemplos del formato de plantillas. La especificación técnica está en español y nombra los campos, los valores y los códigos tal como los escribe y los devuelve la plataforma.

El formato del documento de plantilla​

Es el documento JSON que guarda una plantilla del editor de correo de la plataforma y a partir del cual se genera el HTML del correo. Junto con este texto, el formato se entrega como un JSON Schema (draft 2020-12), schema: la estructura de cada nodo, el tipo y las restricciones de cada propiedad, y lo que vale cada una cuando falta. El schema de un tipo de módulo también se entrega por su cuenta, con un módulo de ejemplo de ese tipo.

En la API de plantillas, con schema=structure el schema del formato trae solo el anidamiento (página, filas, columnas y el sobre de cada módulo) y deja cada tipo a la consulta que lo entrega.

La API de plantillas lee y escribe el documento completo, en config. Guarda el documento normalizado: escribe cada propiedad que tiene default en el schema. Lo que devuelve es ese documento, así que leer una plantilla y enviarla de vuelta sin cambios no cambia nada. Un documento completo mínimo, skeleton, se entrega a pedido (?include=skeleton), como ejemplo del anidamiento.

Estructura​

{ "page": {
"title": "…", the <title> of the HTML
"body": { … }, page properties: font, colors, width
"rows": [ top to bottom
{ "uuid", "if", "for", the row's Liquid blocks, optional
"container", "content",
"columns": [ left to right
{ "uuid", "grid-columns", "style",
"modules": [ top to bottom
{ "uuid", "type", "descriptor": { … } } ] } ] } ] },
"sampleValues": { … } } values for the preview, never sent

Las anotaciones del bloque están en inglés: el título es el título del HTML, el cuerpo lleva las propiedades de la página (fuente, colores, ancho), las filas y los módulos van de arriba abajo, las columnas de izquierda a derecha, una fila puede llevar sus bloques de Liquid, y la raíz guarda los valores de la vista previa, que nunca se envían.

  • page.body: su type es fidelizador-page-properties. content.style.font-family es la fuente de la página, content.computedStyle.linkColor su color de enlace y messageWidth el ancho de todas las filas (si falta, cada fila conserva el suyo; lo habitual es 600px). container.style.background-color es el color alrededor del mensaje. La página no tiene color de texto: cada fila y cada texto llevan el suyo.
  • Una fila es una franja del correo. container.style pinta el ancho completo (un color o una imagen de fondo) y content.style el ancho del mensaje. content.computedStyle.rowColStackOnMobile apila sus columnas en un teléfono. if la muestra solo cuando se cumple una condición y for la repite por cada elemento de una lista (ver Campos).
  • Una columna ocupa grid-columns de las 12 unidades de la fila. Las unidades de las columnas de una fila suman 12: [12], [6, 6], [4, 8], [3, 3, 3, 3].
  • Un módulo es un bloque de contenido. Su type es fidelizador-modules-<kind>.

El formato es cerrado: una propiedad que el schema no declara es un error, en cualquier nivel, propiedades CSS incluidas.

Qué significa una propiedad ausente​

Cada propiedad del schema dice lo que vale su ausencia:

  • Con default: la propiedad toma ese valor. Puede omitirse; la plataforma la escribe.
  • Con x-initial, sin default y no obligatoria: si falta, hereda del nivel superior. El color del texto de un bloque viene de su fila, un color de enlace de la página, una fuente de la página. Un bloque nuevo empieza con el valor de x-initial; si el x-initial es null, empieza heredando.
  • Obligatoria: el nodo no está completo sin ella: un uuid, un grid-columns, el type de un módulo y su contenido.
  • Ninguna de las anteriores: un ajuste opcional; si falta, rige el comportamiento base (un margen en el teléfono, el inicio de una lista numerada).

La página es la raíz de la herencia: su fuente (por defecto la del sistema, 'Segoe UI', …), su color de enlace (#1C93CA) y su fondo (#FFFFFF) tienen un valor por defecto propio. Como no tiene nada por encima, la fuente de la página no puede ser inherit.

Ids​

Cada fila, columna y módulo lleva un uuid, único en el documento. Una edición se dirige a un nodo por él, así que dos nodos con el mismo id pueden hacer que una edición caiga en el que no corresponde. El validador rechaza un id ausente o repetido.

  • Conserve el uuid de cada nodo que ya existe.
  • Un nodo nuevo recibe un id nuevo. Al copiar un nodo, la copia y cada nodo que contiene reciben ids nuevos.
  • Un documento en HTML crudo no tiene filas y, por lo tanto, no tiene ids. Lleva mode, rawHtml y, como mucho, una page vacía ({"rows": []}); es cerrado como el visual.

Módulos​

Cada módulo guarda su contenido en una clave del descriptor. Las rutas de la tabla son relativas a descriptor.

  • Espaciado: va en descriptor.style (padding-*).
  • Aspecto del contenido: el color y el tamaño de un texto o los colores de un botón van en el estilo de su propia clave, como descriptor.heading.style.color. Menú e íconos son la excepción: sus ítems no llevan estilo, así que su color va en descriptor.style.color, y los enlaces de un menú toman descriptor.computedStyle.linkColor.
  • Visibilidad: computedStyle.hideContentOnMobile y hideContentOnDesktop ocultan un módulo en el teléfono o en el escritorio.
  • Teléfono: mobileStyle reemplaza algunas propiedades en un teléfono.

Qué propiedades CSS lee cada estilo de un módulo está en su schema: el estilo es allOf del CSS que el formato conoce y de las propiedades que ese módulo muestra.

TipoClave del contenidoQué se fija
headingheadingheading.text (HTML en línea), heading.title (h1…h6), heading.style.color, heading.style.font-size
paragraphparagraphparagraph.html (<p> con formato en línea y enlaces), paragraph.style.color
listlistlist.html (<ul> u <ol>), list.style.color
imageimageimage.src, image.alt, image.href (enlace opcional); su ancho es computedStyle.width
buttonbuttonbutton.label, button.href, button.style.background-color, button.style.color
dividerdividerdivider.style.border-top (1px solid #EDEDED)
spacerspacerspacer.style.height
menumenuItemsListmenuItemsList.items[]: text y link.href; computedStyle.linkColor para los enlaces
socialiconsListiconsList.icons[]: name e image.{src, href, alt}
iconsiconsListiconsList.icons[]: image, alt, href, text; style.color para el texto
videovideovideo.src (la página del video), video.thumbSrc (su imagen)
htmlhtmlhtml.html: marcado que pasa tal cual
tabletabletable.content.headers[].cells[].html, table.content.rows[].cells[].html
countdowncountdowncountdown.until (instante ISO 8601), countdown.labels, sus colores

Un bloque no existe sin su contenido. Un encabezado necesita su texto, un párrafo y una lista su HTML, un botón su etiqueta, un menú un ítem, un bloque de redes sociales o de íconos un ícono, una tabla una fila, un bloque HTML su marcado, un video su src y una cuenta regresiva su until. La imagen es la excepción: sin src se guarda, con una advertencia.

Un contenido sin texto visible ("", <p></p>, <p><br></p>) no es contenido. Para dejar espacio vertical, use un spacer, no un párrafo vacío.

Un bloque nuevo del editor empieza con un contenido de muestra (x-initial). Si ese contenido sigue sin cambios, genera una advertencia, para que no llegue a un destinatario.

Los arreglos (items, icons, cells) son valores, no se combinan: definir uno lo reemplaza completo.

Valores​

Estos son los tipos de valor que acepta el schema. Conviene conocerlos antes de escribir un valor:

TipoAceptaEjemplo
objeto / arregloexactamente eso; un texto donde va un objeto es un error, nunca un atajo"descriptor": {"paragraph": {…}}, no "descriptor": "Hola"
colorhexadecimal (#RGB, #RRGGBB, con alfa), rgb()/rgba(), hsl(), transparent, un nombre de color CSS#1F2933
lengthun número con su unidad (px, %, em, rem, pt), 0, auto; hasta cuatro para padding y border-radius10px, 0 8px
line_heightuna medida, un porcentaje o un factor sin unidad150%, 1.5
sizeun número, o un número de píxeles o un porcentaje como texto600, "600px"
urlhttps://, http://, mailto:, tel:, un enlace especial fide:, una ruta relativa a la raíz, # (un enlace provisorio), vacío (sin enlace) o un campo completo ({{URL}})https://example.com/oferta
imagehttps:// o una ruta relativa a la raíz de la galería, o vacío/mail-templates/logo.png
htmlHTML, nunca Markdown: <strong>, <a href>, <br><p>Hola <strong>Ana</strong></p>
dateISO 86012030-12-31T23:59:00-03:00
grid-columnsun número entero de 1 a 126

"" es un valor solo en el texto libre y en los enlaces: un alt, un title, un href, una etiqueta de la cuenta regresiva. En cualquier otro lugar (un color, una medida, una fuente, un borde) no significa nada y se rechaza: para tener el valor por defecto, omita la propiedad. Los números son finitos y tienen como máximo 15 dígitos. Un valor CSS es solo el valor: sin ;, sin una segunda declaración, sin comillas alrededor.

Campos​

Un texto puede llevar los valores de cada destinatario, escritos en Liquid. {{ KEY }} toma el valor del campo KEY, y {{ KEY | default: "fallback" }} toma fallback, el respaldo, cuando el destinatario no lo tiene o lo tiene vacío. La clave es la del campo: letras sin tilde, dígitos y _, hasta 64. Se lee sin distinguir mayúsculas, así que {{first_name}} y {{FIRST_NAME}} nombran el mismo campo. {{EMAIL}} es siempre la dirección del destinatario.

Un bloque muestra o repite una parte del correo: {% if CUPON %}...{% else %}...{% endif %} la muestra solo cuando el destinatario tiene un valor, y {% for item in LISTA %}...{% endfor %} la repite por cada elemento. Un bloque puede abrirse en un texto y cerrarse en otro, siempre que el correo lo cierre.

Una fila puede llevar el bloque ella misma: "if": "PUNTOS > 1000" muestra la fila solo cuando se cumple la condición, y "for": "item in PEDIDO.items" la repite una vez por elemento, que sus textos leen como {{ item.producto }}. Cada uno es el contenido de la etiqueta de Liquid, escrito como lo escribe Liquid. El motor pone la etiqueta alrededor de la fila, con la condición por fuera del bucle cuando la fila lleva las dos. Una fila del módulo tabla también acepta for, y se repite como una fila de la tabla. Escrito en la fila, un bloque nunca deja el HTML del correo a medio abrir.

Las comparaciones son las de Liquid. contains lee un texto o una lista, nunca un número. Dos textos se comparan exactamente, mayúsculas incluidas. Una lista vacía es verdadera: {% if PEDIDO.items.size > 0 %} pregunta si tiene elementos. Una fila de tabla repetida conserva el fondo de su posición y no alterna.

Importante

Un texto no se compara con un número. {% if PUNTOS > 1000 %} falla cuando PUNTOS llega como "1500", y a ese destinatario no se le envía el correo. En un envío por la API, mande los números como número.

Un valor conserva el tipo con que llega. Una campaña manda un número de la lista como número, así que {% if PUNTOS > 1000 %} lo compara; un sí/no como true o false, una fecha como 2026-10-22, una selección como la clave de su opción y una selección múltiple como la lista de las claves de sus opciones. La etiqueta de una opción es {{ CIUDAD.label }}, y {{ INTERESES | map: "label" | join: ", " }} escribe las de una selección múltiple. Un envío por la API también puede traer listas y objetos: {{ PEDIDO.numero }} lee un miembro, y una clave dentro de un objeto se lee tal como se escribió.

Un filtro cambia cómo se escribe un valor: los filtros de Liquid salvo safe, más tres en español de Chile. currency escribe pesos ({{ TOTAL | currency }} es $15.990; currency: "USD" para otra moneda), number escribe 1.234,5 (number: format: "#,##0.00" fija los decimales) y datetime escribe una fecha en hora de Santiago ({{ VENCE | datetime: format: "dd/MM/yyyy" }}). currency y number leen un número, o un texto con punto decimal y sin separador de miles (1234.5); cualquier otro texto sale tal como viene. round redondea la mitad hacia arriba.

Un campo sirve en cualquier texto, el asunto incluido, y en un enlace: un enlace completo puede ser un campo ({{URL}}), y un campo puede ir dentro de uno (https://example.com/canje?c={{CODE}}). El valor no se codifica para URL: un espacio, un & o un # en el valor cambian el enlace. Para llevar un dato en un enlace, use un campo cuyos valores no tengan esos caracteres, como un código.

En el HTML el valor se escapa, de modo que se ve como texto y nunca como marcado. El respaldo va entre comillas dobles o simples y es texto de la propia plantilla, que no se escapa; lleva cualquier cosa salvo su propia comilla. Al guardar, un texto, o el if o el for de una fila, que no es una plantilla válida se rechaza con template_syntax_error: un bloque sin cerrar, un filtro fuera de la lista o un respaldo escrito {{KEY|fallback}} en vez de con default. Lo que puede costar el correo de un destinatario tiene límites: 10.000 vueltas de un bucle, 2 MB de salida y 100 ms por parte; el correo que pasa uno no se envía a ese destinatario. Al guardar, una clave que no nombra ningún campo genera la advertencia merge_field_not_in_catalog: ninguna lista puede traer un valor para ella. Un envío por la API sí puede traer su valor.

sampleValues, en la raíz del documento, lleva los valores con que una vista previa completa la plantilla cuando la petición no trae vars, como llegarían para un destinatario: {"PUNTOS": 1500, "PEDIDO": {"items": [{"producto": "Polera"}]}}. Siguen las reglas de vars en un envío: claves en cualquier combinación de mayúsculas, sin EMAIL y con los mismos límites. Al guardar, unos que no las cumplen se rechazan con el error sample_values_invalid en /sampleValues. El motor no los lee, y ningún envío los lleva.

Reglas de calidad​

El validador informa estas reglas, con uno de dos niveles. Un error impide guardar. Indica que el schema rechaza el documento, que la plantilla no se podría generar, que el correo llevaría algo inseguro o que la estructura es ambigua. Una advertencia indica que el correo se genera, pero algún destinatario recibe un correo roto. Cada hallazgo indica el puntero JSON del valor y cómo corregirlo.

NivelCódigoRegla
errorinvalid_document, invalid_structureLa forma de arriba: page, rows, columns y modules están donde corresponde
errorinvalid_typeUn campo tiene el tipo que declara el schema: un objeto, un arreglo, un texto, un número o un booleano
errorunknown_keyUna propiedad que el schema no declara, en cualquier nivel, propiedades CSS incluidas. Suele ser un error de tipeo
errorinvalid_color, invalid_lengthUn color o una medida son de los que entiende un cliente de correo
errorinvalid_enumUn campo con un conjunto cerrado de valores toma uno de ellos (title es h1…h6, en minúsculas), y nunca uno que el campo excluye (inherit en la fuente de la página)
errorempty_valueUna propiedad vale "" donde no lo admite: un color, una medida, un número, una fuente, un valor de una lista. Omítala: si tiene valor por defecto lo toma, y si hereda toma el del nivel de arriba. Un campo de contenido obligatorio vacío es empty_content
errorinvalid_linkUn campo de enlace tiene una URL completa, no www.… y sin espacios
errorinvalid_image_srcUna imagen es una URL https:// o una ruta de la galería; http:, data: y las rutas relativas no se muestran
errorinvalid_dateUna cuenta regresiva cuenta hasta un momento válido
errorinvalid_numberUn número es finito y tiene como máximo 15 dígitos
errormissing_id, duplicate_idCada fila, columna y módulo tiene su propio uuid
errorempty_rowUna fila tiene al menos una columna
errorinvalid_gridCada columna tiene grid-columns, un número entero de 1 a 12
errorunknown_module_typeCada módulo es de un tipo que el formato declara
errorshort_typeUn documento completo escribe el tipo del módulo con su prefijo fidelizador-modules-
errorempty_contentUn bloque tiene su contenido: un botón su etiqueta, un texto sus palabras, un menú sus ítems y cada ítem su texto
errorunsafe_linkNingún enlace ni imagen ejecuta código: javascript:, vbscript: o un enlace data:
errorunsafe_htmlNingún <script>, <iframe>, <object>, <embed>, <form>, <meta>, <base>, <style>, <link>, manejador de eventos (onclick=) ni script en un estilo en línea
errorunbalanced_htmlCada <td> que abre el HTML, lo cierra
errorunsafe_css_valueUn valor CSS no lleva ", ;, <, >, {, } ni barra invertida: un valor por clave
errortemplate_html_too_largeEl rawHtml de un documento de HTML crudo se queda por debajo de 100 KB, lo máximo que guarda una plantilla
errorunrenderableEl HTML del correo se puede generar a partir del documento. Aparece cuando la generación falla y ninguna regla de arriba dice por qué
warninginvalid_link, placeholder_linkUn enlace dentro de un texto es una URL completa, no www.…, no un href vacío; y ningún enlace es un # provisorio. Dentro de un texto, un enlace inválido es una advertencia; en un campo de enlace es un error
warningmalformed_html, markdown_in_htmlLas etiquetas se cierran en el orden en que se abren, y el texto es HTML y no Markdown
warninggrid_not_twelveLos grid-columns de una fila suman 12
warningcountdown_expiredUna cuenta regresiva cuenta hasta un momento futuro
warningunusual_widthmessageWidth está entre 320 y 900 píxeles
warningempty_documentLa página tiene filas
warningimage_without_src, image_without_altUna imagen muestra algo, y dice qué muestra
warningbutton_without_linkUn botón enlaza a alguna parte
warningtext_without_colorUn texto, o la fila en la que está, declara un color. El HTML declara esquemas de color claro y oscuro, así que un texto sin color se pinta claro en modo oscuro y puede desaparecer
warningstyle_ignoredUn estilo declara solo propiedades que el correo muestra: un background-color en un párrafo, o un color en la página, es CSS válido que nunca llega al HTML
warningsample_contentUn bloque ya no lleva el contenido de muestra con que se creó
warningclick_here_without_linkUn texto que pide un clic lleva el enlace
warningunresolved_special_link, missing_special_linkLos enlaces especiales obligatorios son fide:unsubscribe, fide:complaint y fide:browser-view, y un correo lleva los tres, normalmente en el pie
warninggmail_clipEl HTML se queda por debajo de 100 KB, donde Gmail recorta el mensaje y oculta el resto. El hallazgo trae el peso que midió en size_bytes

Las imágenes vienen de la galería de la plataforma o de la biblioteca de la cuenta, por ruta relativa a la raíz (/mail-templates/…) o por la URL completa que trae un documento guardado. Los enlaces especiales van en href.

La vista esencial​

Esta parte aplica al conector MCP y a la plantilla que el editor copia para un chat de IA. La API de plantillas no acepta la vista esencial.

El conector MCP trabaja sobre una forma más corta del mismo documento: su vista esencial. Tiene la misma forma, pero solo con lo que difiere de los valores por defecto, así que es más corta. El schema que recibe el conector es el de la vista.

  • La plataforma convierte una vista de vuelta en el documento completo: escribe cada valor por defecto y le da un uuid a cada fila, columna y módulo que no lo tenga, así que un nodo que se agrega a una vista no necesita id. La vista de un documento vuelve a ser exactamente ese documento.
  • En una vista, el type de un módulo puede ser el <kind> solo, sin el prefijo fidelizador-modules-.
  • null significa "hereda". Una propiedad que hereda y que el documento guardado omite aparece en la vista como null: el bloque la toma de su fila o de la página. null se acepta solo en esas propiedades. Una cuyo valor inicial es null (el color de enlace de un encabezado) simplemente no aparece en la vista, porque ausente ya significa que hereda.
  • Una propiedad que hereda y que la vista omite toma su valor inicial (x-initial), como un bloque que el usuario agrega en el editor. Para que un bloque nuevo herede, escriba null.
  • El contenido nunca se completa: un bloque cuyo contenido la vista omite se rechaza.
  • El conector recibe el schema del anidamiento solo, y pide el de los tipos de módulo que necesita, varios en una llamada. Una copia del formato pegada en un chat lleva en cambio el schema completo, con todos los tipos.
  • Los ejemplos del formato son vistas esenciales: uno por tipo de módulo, una fila de dos columnas (two-columns) y un correo completo (skeleton). Sirven cuando el anidamiento no queda claro o el validador informa un error de estructura. No llevan uuid: la plataforma le da a cada nodo el suyo al guardar, así que pegar dos ejemplos nunca repite un id.

Ejemplo de anidamiento (skeleton)​

Es el documento completo que devuelve GET /v1/mail-templates/format?include=skeleton: un correo mínimo con cada valor por defecto escrito, como lo guarda una plantilla. La versión en vista esencial, más corta, está en Ejemplos del formato.

{
"page": {
"title": "Esqueleto",
"rows": [
{
"uuid": "row-example-11",
"columns": [
{
"uuid": "column-example-11",
"grid-columns": 12,
"modules": [
{
"uuid": "heading-example-2",
"type": "fidelizador-modules-heading",
"descriptor": {
"heading": {
"text": "Título",
"title": "h1",
"style": {
"color": "#190908",
"link-color": "#1C93CA",
"font-family": "inherit",
"font-size": "24px",
"font-weight": "700",
"line-height": "120%",
"letter-spacing": "0px",
"text-align": "left",
"direction": "ltr"
},
"computedStyle": {
"paragraphSpacing": "0px"
}
},
"style": {
"padding-top": "10px",
"padding-right": "10px",
"padding-bottom": "10px",
"padding-left": "10px"
},
"computedStyle": {
"hideContentOnMobile": false,
"hideContentOnDesktop": false
}
}
},
{
"uuid": "paragraph-example-2",
"type": "fidelizador-modules-paragraph",
"descriptor": {
"paragraph": {
"html": "<p>Texto del correo.</p>",
"style": {
"color": "#606060",
"font-family": "inherit",
"font-size": "16px",
"font-weight": "400",
"line-height": "150%",
"letter-spacing": "0px",
"text-align": "left",
"direction": "ltr"
},
"computedStyle": {
"linkColor": "#1C93CA",
"paragraphSpacing": "0px"
}
},
"style": {
"padding-top": "10px",
"padding-right": "10px",
"padding-bottom": "10px",
"padding-left": "10px"
},
"computedStyle": {
"hideContentOnMobile": false,
"hideContentOnDesktop": false
}
}
},
{
"uuid": "button-example-2",
"type": "fidelizador-modules-button",
"descriptor": {
"button": {
"label": "Ver más",
"href": "https://example.com",
"style": {
"color": "#ffffff",
"background-color": "#0c6cc7",
"border-top": "0px solid #000000",
"border-right": "0px solid #000000",
"border-bottom": "0px solid #000000",
"border-left": "0px solid #000000",
"border-radius": "5px",
"padding-top": "13px",
"padding-right": "30px",
"padding-bottom": "13px",
"padding-left": "30px",
"width": "100%",
"font-family": "inherit",
"font-size": "16px",
"font-weight": "700",
"line-height": "120%",
"letter-spacing": "0px"
}
},
"style": {
"padding-top": "10px",
"padding-right": "10px",
"padding-bottom": "10px",
"padding-left": "10px",
"text-align": "center"
},
"computedStyle": {
"hideContentOnMobile": false,
"hideContentOnDesktop": false,
"width": 120,
"height": 42
}
}
}
],
"style": {
"background-color": "transparent",
"border-top": "0px solid transparent",
"border-right": "0px solid transparent",
"border-bottom": "0px solid transparent",
"border-left": "0px solid transparent",
"padding-top": "5px",
"padding-right": "0px",
"padding-bottom": "5px",
"padding-left": "0px"
}
}
],
"container": {
"style": {
"background-color": "transparent",
"background-image": "none",
"background-position": "top left",
"background-repeat": "no-repeat",
"background-size": "cover"
}
},
"content": {
"style": {
"color": "#000000",
"background-color": "transparent",
"background-image": "none",
"background-position": "top left",
"background-repeat": "no-repeat",
"background-size": "cover",
"border-top": "0px solid transparent",
"border-right": "0px solid transparent",
"border-bottom": "0px solid transparent",
"border-left": "0px solid transparent",
"border-radius": "0px",
"padding-top": "0px",
"padding-right": "0px",
"padding-bottom": "0px",
"padding-left": "0px",
"width": "600px"
},
"computedStyle": {
"hideContentOnMobile": false,
"hideContentOnDesktop": false,
"rowColStackOnMobile": true,
"rowReverseColStackOnMobile": false,
"verticalAlign": "top",
"columnsSpacing": "0px",
"columnsBorderRadius": "0px"
}
}
},
{
"uuid": "row-example-12",
"columns": [
{
"uuid": "column-example-12",
"grid-columns": 12,
"modules": [
{
"uuid": "paragraph-example-3",
"type": "fidelizador-modules-paragraph",
"descriptor": {
"paragraph": {
"html": "<p><a href=\"fide:browser-view\">Ver en el navegador</a> · <a href=\"fide:unsubscribe\">Darse de baja</a> · <a href=\"fide:complaint\">Reportar abuso</a></p>",
"style": {
"color": "#606060",
"font-family": "inherit",
"font-size": "16px",
"font-weight": "400",
"line-height": "150%",
"letter-spacing": "0px",
"text-align": "left",
"direction": "ltr"
},
"computedStyle": {
"linkColor": "#1C93CA",
"paragraphSpacing": "0px"
}
},
"style": {
"padding-top": "10px",
"padding-right": "10px",
"padding-bottom": "10px",
"padding-left": "10px"
},
"computedStyle": {
"hideContentOnMobile": false,
"hideContentOnDesktop": false
}
}
}
],
"style": {
"background-color": "transparent",
"border-top": "0px solid transparent",
"border-right": "0px solid transparent",
"border-bottom": "0px solid transparent",
"border-left": "0px solid transparent",
"padding-top": "5px",
"padding-right": "0px",
"padding-bottom": "5px",
"padding-left": "0px"
}
}
],
"container": {
"style": {
"background-color": "transparent",
"background-image": "none",
"background-position": "top left",
"background-repeat": "no-repeat",
"background-size": "cover"
}
},
"content": {
"style": {
"color": "#000000",
"background-color": "transparent",
"background-image": "none",
"background-position": "top left",
"background-repeat": "no-repeat",
"background-size": "cover",
"border-top": "0px solid transparent",
"border-right": "0px solid transparent",
"border-bottom": "0px solid transparent",
"border-left": "0px solid transparent",
"border-radius": "0px",
"padding-top": "0px",
"padding-right": "0px",
"padding-bottom": "0px",
"padding-left": "0px",
"width": "600px"
},
"computedStyle": {
"hideContentOnMobile": false,
"hideContentOnDesktop": false,
"rowColStackOnMobile": true,
"rowReverseColStackOnMobile": false,
"verticalAlign": "top",
"columnsSpacing": "0px",
"columnsBorderRadius": "0px"
}
}
}
],
"body": {
"type": "fidelizador-page-properties",
"container": {
"style": {
"background-color": "#FFFFFF"
}
},
"content": {
"style": {
"font-family": "'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif"
},
"computedStyle": {
"linkColor": "#1C93CA"
}
},
"webFonts": []
}
}
}

Cómo trabajar con un chat de IA​

Hay dos formas de que un asistente de IA edite una plantilla:

  • Con el conector MCP. El asistente lee la plantilla y este formato, la edita y la valida por su cuenta. Ver Servidor MCP.
  • Copiando y pegando. En el editor de plantillas, Editar con su asistente de IA abre una ventana de dos pasos. El paso a paso está en Plantillas con un asistente de IA.
    • El primer paso copia su pedido, una indicación para el asistente, un enlace a esta especificación (o la especificación completa en el idioma del panel, si la pide) y la plantilla en vista esencial, con los cambios sin guardar. La indicación pide la plantilla completa en un único bloque de código json, sin texto antes ni después.
    • El segundo recibe la respuesta del asistente tal como sale del chat. El editor encuentra el JSON aunque venga dentro de un bloque de código o con texto alrededor. Rechaza lo que no es una plantilla completa (una explicación, una respuesta cortada o un fragmento sin page) y valida el resto antes de cargarlo. Si encuentra errores, los muestra y ofrece copiarlos para el asistente.

Cargar una plantilla pegada no la guarda. Revise el resultado en el editor y guarde cuando quiera. Si deshace el cambio, vuelve a la plantilla anterior.