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:
GET /v1/mail-templates/formatdevuelve la especificación, su JSON Schema con el tipo y el valor por defecto de cada campo, y la lista de tipos de módulo; a pedido, un ejemplo del anidamiento (skeleton).GET /v1/mail-templates/format/modules/{kind}devuelve el formato de un tipo de módulo, con un módulo completo de ejemplo.
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: sutypeesfidelizador-page-properties.content.style.font-familyes la fuente de la página,content.computedStyle.linkColorsu color de enlace ymessageWidthel ancho de todas las filas (si falta, cada fila conserva el suyo; lo habitual es600px).container.style.background-colores 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.stylepinta el ancho completo (un color o una imagen de fondo) ycontent.styleel ancho del mensaje.content.computedStyle.rowColStackOnMobileapila sus columnas en un teléfono.ifla muestra solo cuando se cumple una condición yforla repite por cada elemento de una lista (ver Campos). - Una columna ocupa
grid-columnsde 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
typeesfidelizador-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, sindefaulty 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 dex-initial; si elx-initialesnull, empieza heredando. - Obligatoria: el nodo no está completo sin ella: un
uuid, ungrid-columns, eltypede 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
uuidde 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,rawHtmly, como mucho, unapagevací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 endescriptor.style.color, y los enlaces de un menú tomandescriptor.computedStyle.linkColor. - Visibilidad:
computedStyle.hideContentOnMobileyhideContentOnDesktopocultan un módulo en el teléfono o en el escritorio. - Teléfono:
mobileStylereemplaza 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.
| Tipo | Clave del contenido | Qué se fija |
|---|---|---|
heading | heading | heading.text (HTML en línea), heading.title (h1…h6), heading.style.color, heading.style.font-size |
paragraph | paragraph | paragraph.html (<p> con formato en línea y enlaces), paragraph.style.color |
list | list | list.html (<ul> u <ol>), list.style.color |
image | image | image.src, image.alt, image.href (enlace opcional); su ancho es computedStyle.width |
button | button | button.label, button.href, button.style.background-color, button.style.color |
divider | divider | divider.style.border-top (1px solid #EDEDED) |
spacer | spacer | spacer.style.height |
menu | menuItemsList | menuItemsList.items[]: text y link.href; computedStyle.linkColor para los enlaces |
social | iconsList | iconsList.icons[]: name e image.{src, href, alt} |
icons | iconsList | iconsList.icons[]: image, alt, href, text; style.color para el texto |
video | video | video.src (la página del video), video.thumbSrc (su imagen) |
html | html | html.html: marcado que pasa tal cual |
table | table | table.content.headers[].cells[].html, table.content.rows[].cells[].html |
countdown | countdown | countdown.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:
| Tipo | Acepta | Ejemplo |
|---|---|---|
| objeto / arreglo | exactamente eso; un texto donde va un objeto es un error, nunca un atajo | "descriptor": {"paragraph": {…}}, no "descriptor": "Hola" |
color | hexadecimal (#RGB, #RRGGBB, con alfa), rgb()/rgba(), hsl(), transparent, un nombre de color CSS | #1F2933 |
length | un número con su unidad (px, %, em, rem, pt), 0, auto; hasta cuatro para padding y border-radius | 10px, 0 8px |
line_height | una medida, un porcentaje o un factor sin unidad | 150%, 1.5 |
size | un número, o un número de píxeles o un porcentaje como texto | 600, "600px" |
url | https://, 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 |
image | https:// o una ruta relativa a la raíz de la galería, o vacío | /mail-templates/logo.png |
html | HTML, nunca Markdown: <strong>, <a href>, <br> | <p>Hola <strong>Ana</strong></p> |
date | ISO 8601 | 2030-12-31T23:59:00-03:00 |
grid-columns | un número entero de 1 a 12 | 6 |
"" 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.
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.
| Nivel | Código | Regla |
|---|---|---|
| error | invalid_document, invalid_structure | La forma de arriba: page, rows, columns y modules están donde corresponde |
| error | invalid_type | Un campo tiene el tipo que declara el schema: un objeto, un arreglo, un texto, un número o un booleano |
| error | unknown_key | Una propiedad que el schema no declara, en cualquier nivel, propiedades CSS incluidas. Suele ser un error de tipeo |
| error | invalid_color, invalid_length | Un color o una medida son de los que entiende un cliente de correo |
| error | invalid_enum | Un 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) |
| error | empty_value | Una 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 |
| error | invalid_link | Un campo de enlace tiene una URL completa, no www.… y sin espacios |
| error | invalid_image_src | Una imagen es una URL https:// o una ruta de la galería; http:, data: y las rutas relativas no se muestran |
| error | invalid_date | Una cuenta regresiva cuenta hasta un momento válido |
| error | invalid_number | Un número es finito y tiene como máximo 15 dígitos |
| error | missing_id, duplicate_id | Cada fila, columna y módulo tiene su propio uuid |
| error | empty_row | Una fila tiene al menos una columna |
| error | invalid_grid | Cada columna tiene grid-columns, un número entero de 1 a 12 |
| error | unknown_module_type | Cada módulo es de un tipo que el formato declara |
| error | short_type | Un documento completo escribe el tipo del módulo con su prefijo fidelizador-modules- |
| error | empty_content | Un bloque tiene su contenido: un botón su etiqueta, un texto sus palabras, un menú sus ítems y cada ítem su texto |
| error | unsafe_link | Ningún enlace ni imagen ejecuta código: javascript:, vbscript: o un enlace data: |
| error | unsafe_html | Ningún <script>, <iframe>, <object>, <embed>, <form>, <meta>, <base>, <style>, <link>, manejador de eventos (onclick=) ni script en un estilo en línea |
| error | unbalanced_html | Cada <td> que abre el HTML, lo cierra |
| error | unsafe_css_value | Un valor CSS no lleva ", ;, <, >, {, } ni barra invertida: un valor por clave |
| error | template_html_too_large | El rawHtml de un documento de HTML crudo se queda por debajo de 100 KB, lo máximo que guarda una plantilla |
| error | unrenderable | El HTML del correo se puede generar a partir del documento. Aparece cuando la generación falla y ninguna regla de arriba dice por qué |
| warning | invalid_link, placeholder_link | Un 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 |
| warning | malformed_html, markdown_in_html | Las etiquetas se cierran en el orden en que se abren, y el texto es HTML y no Markdown |
| warning | grid_not_twelve | Los grid-columns de una fila suman 12 |
| warning | countdown_expired | Una cuenta regresiva cuenta hasta un momento futuro |
| warning | unusual_width | messageWidth está entre 320 y 900 píxeles |
| warning | empty_document | La página tiene filas |
| warning | image_without_src, image_without_alt | Una imagen muestra algo, y dice qué muestra |
| warning | button_without_link | Un botón enlaza a alguna parte |
| warning | text_without_color | Un 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 |
| warning | style_ignored | Un 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 |
| warning | sample_content | Un bloque ya no lleva el contenido de muestra con que se creó |
| warning | click_here_without_link | Un texto que pide un clic lleva el enlace |
| warning | unresolved_special_link, missing_special_link | Los enlaces especiales obligatorios son fide:unsubscribe, fide:complaint y fide:browser-view, y un correo lleva los tres, normalmente en el pie |
| warning | gmail_clip | El 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
uuida 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
typede un módulo puede ser el<kind>solo, sin el prefijofidelizador-modules-. nullsignifica "hereda". Una propiedad que hereda y que el documento guardado omite aparece en la vista comonull: el bloque la toma de su fila o de la página.nullse acepta solo en esas propiedades. Una cuyo valor inicial esnull(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, escribanull. - El contenido nunca se completa: un bloque cuyo contenido la vista omite se rechaza.
- El conector recibe el
schemadel 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 elschemacompleto, 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 llevanuuid: 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.
- 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
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.