BuildDocs Logo

Create Dynamic Word Documents

Master document logic. Implement conditionals, loops for lists, and text variables to automate contracts and reports.

How it works?

Instead of writing "John Doe", you write {{client_name}}. When you upload your file and data, we fill everything automatically.

Text Variables

Use double curly braces to insert dynamic data anywhere in the document.

Simple Variables

Cliente: {{ data.cliente.nombre }}
Fecha: {{ data.fecha }}
Monto: ${{ data.monto }}

Nested Data

Contacto: {{ data.cliente.contacto.nombre }}
Email: {{ data.cliente.contacto.email }}
Cargo: {{ data.cliente.contacto.cargo }}

Images

Insert dynamic images from URLs or base64 data. Two methods available:

1Text Token

The image is inserted at its original size (max 6 inches wide).

{{#picture logo}}

JSON:

{
  "logo": "https://ejemplo.com/logo.png"
}

2Placeholder Image

The image adjusts to the placeholder size maintaining proportions.

Simple Steps:
1. Insert an example image 2. Right click → Alt Text 3. Write the variable name (e.g., logo)

JSON:

{
  "logo": "data:image/png;base64,iVBO..."
}

Supported formats

  • URL pública (https://...)
  • Base64 data URI (data:image/png;base64,...)
  • Formatos: PNG, JPG, GIF, BMP

Smart Tables

Tables expand automatically when they detect array variables. No special syntax needed - just use normal variables.

Example: Product Table

IN YOUR TEMPLATE:

ProductPrice
{{ products.name }}{{ products.price }}

YOUR JSON DATA:

{
  "products": [
    { "name": "Laptop", "price": 1000 },
    { "name": "Mouse", "price": 25 }
  ]
}
The system detects that products is an array and expands the row automatically for each element.

TIPSpecial Variable: Auto Numbering

Use {{#index}} to number rows automatically (1, 2, 3...).

{{ #index }} - {{ products.name }}

Lists

No need to declare loops. The engine automatically detects when a variable is a collection and repeats the list item for each item.

Bulleted List

Create a list in Word and add tokens:

  • {{ items.name }}

Numbered List

Same principle with numbered lists:

  1. {{ items.name }}

Nesting

You can nest collections within other collections. The engine automatically duplicates necessary elements.

Example: Companies with Projects

{{ companies.name }}

Projects:

  • {{ companies.projects.name }}

companies.projects.name accesses projects within each company.

Tip: Duplicable Objects

The engine looks for the nearest duplicable object: table cell, list item, or paragraph. If you need to repeat content that is none of these, use a single-cell table with transparent borders.

Conditional Logic

Show or hide content based on your data.

If/Else

{% if price > 100 %}
  Oferta Especial
{% else %}
  Precio Regular
{% endif %}

Check Existence

{% if discount %}
  Descuento: {{ discount }}%
{% endif %}

Functions and Filters

Transform and manipulate your data

Text Transformation

Custom FiltersExampleResult
title_case{{ "hello world" | title_case }}Hello World
upper{{ name | upper }}JUAN PÉREZ
lower{{ title | lower }}documento
replace{{ text | replace("old", "new") }}text new
length{{ "Hello" | length }}5

Number and Date Formatting

Custom FiltersExampleResult
format{{ 1234.5 | format("N2") }}1,234.50
format (currency){{ price | format("C") }}$1,500.00
format (date){{ date | format("%d/%m/%Y") }}25/12/2024
num2words{{ 42 | num2words }}forty-two

List Operations

Custom FiltersExampleResult
count{{ products | count }}5
join{{ names | join(", ") }}Ana, Carlos, Luis
sort{{ items | sort("name") }}[sorted A-Z]
filter{{ items | filter("active == true") }}[only active]
sum{{ orders | sum("total") }}4,500.00
avg{{ scores | avg }}85.5

Checks

Custom FiltersExampleResult
is_empty{% if list | is_empty %}No data{% endif %}true/false
contains{{ email | contains("@gmail") }}true/false
starts_with{{ code | starts_with("PRO-") }}true/false
ends_with{{ file | ends_with(".pdf") }}true/false
default{{ name | default("N/A") }}N/A

Advanced Data Access

Filters to access complex and nested data in your JSON.

Custom FiltersSyntax
findFinds the first element where a field equals a value
first / lastGets the first or last element of a list
attrGets an attribute of an object
selectattrFilters elements by attribute
map_attrExtracts an attribute from each element

Example: Filter and Access Sublines

To iterate only FINANCE sublines:

{% set finance = data.catalogo_global.lineas_negocio | find("codigo", "FINANCE") %}
{% for sub in finance.sublineas %}
• {{ sub.nombre }}
{% endfor %}

Result: Treasury Management, Working Capital Management, Financial Operations...

NUMERACIÓNAutomatic Section Numbering

Numbers sections automatically, even when some are hidden with {%if%} (Jinja2).

Syntax

{{ #section(7) }} Introducción
{% if show_overview %}
{{ #section(7) }} Resumen General
{% endif %}
{{ #section(7) }} Detalles del Proyecto

Without auto-numbering (show_overview=false)

7.1 Introducción
7.3 Detalles (hueco)

With auto-numbering

7.1 Introducción
7.2 Detalles ✓

Tip: Supports multiple levels: {{ #section(7.1) }} → 7.1.1, 7.1.2...

LÓGICALogical Operations

If/Else

{% if cliente.tipo == 'premium' %}
  Estimado cliente VIP,
{% elif cliente.tipo == 'regular' %}
  Estimado cliente,
{% else %}
  A quien corresponda,
{% endif %}

Combining with Filters

{% if items | is_empty %}
  No hay elementos
{% else %}
  Total: {{ items | count }} elementos
  Suma: {{ items | sum("precio") | format("C") }}
{% endif %}

Best Practices

  • Combine filters: {{ items | filter("activo == true") | count }}
  • Use default for missing values
  • Format numbers and dates for professional presentation
BuildDocs | Automated PPTX & DOCX Generation API