Sintaxis de plantillas
Las plantillas son archivos .docx editables con Microsoft Word o LibreOffice. El motor de render es docxtemplater. Se soporta dot-notation (ej. {persona.nombre}), loops, condicionales e imágenes con reglas estrictas de tamaño.
Variables simples
Encierra el nombre del campo entre llaves:
Folio: {folio}
Cliente: {cliente.nombre}
Importe total: {total}{
"folio": "F-001",
"cliente": { "nombre": "Acme S.A." },
"total": 1500
}Dot-notation (objetos anidados)
Funciona con cualquier nivel de anidamiento: {a.b.c.d}. Si el path no resuelve, sale string vacío (no aparece la palabra "undefined" en el documento).
Generado por {persona.nombre} {persona.primer_apellido} {persona.segundo_apellido}Loops
Usa {#variable}...{/variable}. La variable debe ser un array. Dentro del loop, cada elemento del array se vuelve el scope.
Conceptos:
{#items}
- {descripcion} (cantidad: {cantidad})
{/items}{
"items": [
{ "descripcion": "Servicio mensual", "cantidad": 12 },
{ "descripcion": "Soporte premium", "cantidad": 1 }
]
}Loops dentro de tablas Word
Para repetir filas de tabla, pon {#items} al inicio de la primera celda de la fila plantilla y {/items} al final de la última celda. docxtemplater detecta el patrón y duplica la fila completa por cada elemento.
Condicionales
Misma sintaxis que loops, pero con un valor escalar truthy/falsy. Si el valor es true, número distinto de cero, o string no vacío, el bloque se renderiza. Si es false, null, undefined,0 o array vacío, se omite.
{#descuento}Descuento aplicado: {descuento}%{/descuento}Imágenes
Usa el prefijo % en el tag: {%logo}. El valor en data.logo debe ser uno de:
- Data URI base64:
data:image/png;base64,... - URL HTTP/HTTPS: ej.
https://cdn.clickbalance.com/logo.png. Pasa por SSRF guard (rechaza IPs privadas, loopback, link-local). - Ruta relativa a
IMAGES_DIR: ej.logos/empresa-acme.png. La carpeta se monta como volumen externo.
Toda etiqueta {%tag} debe estar en una celda de tabla 1×1.
El ancho de la celda determina el ancho de la imagen renderizada. La altura se calcula automáticamente respetando el aspect ratio nativo del archivo (PNG/JPEG/GIF). Si pones la etiqueta fuera de una tabla, el render falla con RENDER_ERROR:
{
"error": {
"code": "RENDER_ERROR",
"message": "Image placeholders {%tag} must be inside a 1x1 table cell. Found outside a cell: {%logo}",
"details": { "orphans": ["logo"] }
}
}Cómo crear la celda en Word
- Posiciónate donde quieres la imagen.
- Insert → Table → 1 fila × 1 columna.
- Ajusta el ancho de la columna al ancho deseado para la imagen.
- Dentro de la celda, escribe
{%logo}. - Opcional: oculta los bordes de la tabla si no los quieres visibles.
Límites
- Tamaño máx por imagen:
MAX_IMAGE_MB(default 5 MB). - Timeout de fetch HTTP:
HTTP_FETCH_TIMEOUT_MS(default 10 s). - SSRF: se rechazan rangos
10/8,127/8,169.254/16,172.16/12,192.168/16,::1,fc00::/7,fe80::/10.
Sintaxis completa de docxtemplater
La referencia completa está en docxtemplater.com/docs/tag-types. Lo que no está activado en este servicio:
- Inverted sections (
{^items}...{/items}) — funcionan, sólo no documentadas aquí. - Custom angular-expressions — usamos un parser de dot-notation simple, no expresiones aritméticas.
- Subtemplates — no soportados.