Saltar a contenido

Jinja2 Templates

Fracttal ETL Hub utiliza plantillas Jinja2 para generar contenido dinámico durante las transformaciones. Las plantillas permiten crear documentos, emails, y contenido personalizado basado en datos de entrada.

Sintaxis Básica

Variables

Hola {{ name }} {{ lastname }}

Tu edad es: {{ age }}

Filtros

{{ name | upper }}
{{ price | round(2) }}
{{ date | strftime('%d/%m/%Y') }}

Condicionales

{% if age >= 18 %}
Eres mayor de edad
{% else %}
Eres menor de edad
{% endif %}

Bucles

{% for item in items %}
- {{ item.name }}: {{ item.price }}
{% endfor %}

Filtros Personalizados

Filtros de Texto

slugify

Convierte texto a slug URL-friendly.

{{ "Hola Mundo!" | slugify }}
<!-- Output: hola-mundo -->

truncate

Trunca texto a una longitud específica.

{{ "Este es un texto muy largo" | truncate(10) }}
<!-- Output: Este es... -->

Filtros Numéricos

currency

Formatea números como moneda.

{{ 1234.56 | currency('CLP') }}
<!-- Output: $1.234 -->

percentage

Convierte decimal a porcentaje.

{{ 0.85 | percentage }}
<!-- Output: 85% -->

Filtros de Fecha

relative_date

Muestra fecha relativa.

{{ created_at | relative_date }}
<!-- Output: hace 2 días -->

business_days

Calcula días hábiles.

{{ start_date | business_days(end_date) }}
<!-- Output: 5 -->

Plantillas para Emails

Email de Bienvenida

Asunto: Bienvenido a {{ company_name }}

Estimado {{ user.name }},

¡Bienvenido a {{ company_name }}!

Tu cuenta ha sido creada exitosamente con los siguientes datos:
- Usuario: {{ user.username }}
- Email: {{ user.email }}
- Fecha de registro: {{ user.created_at | strftime('%d/%m/%Y') }}

Para activar tu cuenta, haz click en el siguiente enlace:
{{ activation_url }}

Atentamente,
El equipo de {{ company_name }}

Email de Notificación de Orden

Asunto: Orden #{{ order.id }} - {{ order.status | title }}

Hola {{ customer.name }},

{% if order.status == 'confirmed' %}
Tu orden ha sido confirmada y está siendo procesada.
{% elif order.status == 'shipped' %}
Tu orden ha sido enviada.
{% elif order.status == 'delivered' %}
Tu orden ha sido entregada.
{% endif %}

Detalles de la orden:
- Número: {{ order.id }}
- Fecha: {{ order.created_at | strftime('%d/%m/%Y %H:%M') }}
- Total: {{ order.total | currency('CLP') }}

{% if order.tracking_number %}
Número de seguimiento: {{ order.tracking_number }}
{% endif %}

Productos:
{% for item in order.items %}
- {{ item.product.name }} x{{ item.quantity }} - {{ item.total | currency('CLP') }}
{% endfor %}

Gracias por tu compra.

Saludos,
{{ company_name }}

Plantillas para Documentos

Reporte de Ventas

# Reporte de Ventas - {{ period }}

Generado: {{ now | strftime('%d/%m/%Y %H:%M') }}

## Resumen Ejecutivo

- Total Ventas: {{ sales.total | currency('CLP') }}
- Número de Órdenes: {{ sales.orders_count }}
- Ticket Promedio: {{ sales.average_ticket | currency('CLP') }}
- Crecimiento vs Mes Anterior: {{ sales.growth | percentage }}

## Ventas por Categoría

| Categoría | Ventas | Participación |
|-----------|--------|--------------|
{% for category in sales.by_category %}
| {{ category.name }} | {{ category.total | currency('CLP') }} | {{ category.percentage | percentage }} |
{% endfor %}

## Top Productos

{% for product in sales.top_products %}
### {{ product.name }}
- Ventas: {{ product.sales | currency('CLP') }}
- Unidades: {{ product.units }}
- Margen: {{ product.margin | percentage }}
{% endfor %}

Factura

{{ company.name }}
{{ company.address }}
{{ company.phone }} | {{ company.email }}

FACTURA #{{ invoice.number }}

Fecha: {{ invoice.date | strftime('%d/%m/%Y') }}
Cliente: {{ invoice.customer.name }}
RUT: {{ invoice.customer.rut }}

================================================================================
Producto/Descripción                    Cantidad    Precio      Total
================================================================================
{% for item in invoice.items %}
{{ item.description | truncate(35) | ljust(35) }} {{ item.quantity | rjust(8) }} {{ item.price | currency('CLP') | rjust(10) }} {{ item.total | currency('CLP') | rjust(10) }}
{% endfor %}
================================================================================
SUBTOTAL: {{ invoice.subtotal | currency('CLP') | rjust(70) }}
IVA (19%): {{ invoice.tax | currency('CLP') | rjust(70) }}
TOTAL:    {{ invoice.total | currency('CLP') | rjust(70) }}

Vencimiento: {{ invoice.due_date | strftime('%d/%m/%Y') }}

Plantillas para APIs

Payload JSON Dinámico

{
  "order": {
    "id": "{{ order.id }}",
    "customer": {
      "name": "{{ customer.name }}",
      "email": "{{ customer.email }}"
    },
    "items": [
      {% for item in order.items %}
      {
        "product_id": "{{ item.product.id }}",
        "name": "{{ item.product.name }}",
        "quantity": {{ item.quantity }},
        "price": {{ item.price }}
      }{% if not loop.last %},{% endif %}
      {% endfor %}
    ],
    "total": {{ order.total }},
    "status": "{{ order.status }}",
    "created_at": "{{ order.created_at | strftime('%Y-%m-%dT%H:%M:%SZ') }}"
  }
}

XML para Sistemas Legacy

<?xml version="1.0" encoding="UTF-8"?>
<Order>
  <OrderNumber>{{ order.id }}</OrderNumber>
  <Customer>
    <Name>{{ customer.name }}</Name>
    <Email>{{ customer.email }}</Email>
    <Phone>{{ customer.phone }}</Phone>
  </Customer>
  <Items>
    {% for item in order.items %}
    <Item>
      <ProductCode>{{ item.product.code }}</ProductCode>
      <Description>{{ item.product.name }}</Description>
      <Quantity>{{ item.quantity }}</Quantity>
      <UnitPrice>{{ item.price }}</UnitPrice>
      <Total>{{ item.total }}</Total>
    </Item>
    {% endfor %}
  </Items>
  <Totals>
    <Subtotal>{{ order.subtotal }}</Subtotal>
    <Tax>{{ order.tax }}</Tax>
    <Total>{{ order.total }}</Total>
  </Totals>
  <OrderDate>{{ order.created_at | strftime('%Y-%m-%d') }}</OrderDate>
</Order>

Configuración en ETL

Usando Templates en Transformaciones

{
  "source": {
    "connection": {"id_type": 1, "name": "Database"},
    "operation": "list_table",
    "parameters": {"table": "orders"}
  },
  "transform": {
    "template": {
      "file": "invoice_template.html",
      "context": {
        "order": {"var": "data"},
        "customer": {"lookup": ["customer_id", "customers", "id"]},
        "company": {"var": "company_info"}
      }
    }
  },
  "target": {
    "connection": {"id_type": 3, "name": "Email"},
    "operation": "send",
    "parameters": {
      "to": {"var": "customer.email"},
      "subject": "Factura #{{ order.id }}",
      "body": {"var": "template_output"}
    }
  }
}

Templates Inline

{
  "transform": {
    "template_string": {
      "template": "Hola {{ name }}, tu saldo es {{ balance | currency('CLP') }}",
      "context": {
        "name": {"var": "customer_name"},
        "balance": {"var": "account_balance"}
      }
    }
  }
}

Mejores Prácticas

1. Organiza tus Templates

templates/
├── emails/
│   ├── welcome.html
│   ├── order_confirmation.html
│   └── invoice.html
├── reports/
│   ├── sales_report.html
│   └── inventory_report.html
└── api/
    ├── order_payload.json
    └── customer_sync.xml

2. Usa Context Helpers

def prepare_template_context(data):
    return {
        'customer': data.get('customer', {}),
        'order': data.get('order', {}),
        'company': get_company_info(),
        'format_currency': lambda x: f"${x:,.0f}",
        'now': datetime.now()
    }

3. Maneja Errores

{% if customer.name %}
Hola {{ customer.name }},
{% else %}
Estimado cliente,
{% endif %}

4. Optimiza Rendimiento

  • Compila templates frecuentemente usados
  • Cachea resultados cuando sea posible
  • Usa variables locales en bucles grandes

Variables Globales

Fracttal ETL proporciona variables globales disponibles en todas las templates:

  • now: Fecha/hora actual
  • company: Información de la compañía
  • environment: Entorno actual (production/develop)
  • user: Usuario que ejecuta el ETL
Generado por: {{ user.name }}
En entorno: {{ environment }}
Fecha: {{ now | strftime('%d/%m/%Y %H:%M') }}

Depuración

Para depurar templates, usa el operador debug:

{
  "transform": {
    "debug": {
      "template": "template_name",
      "context": {"var": "data"}
    }
  }
}

Esto mostrará el contexto disponible y el resultado renderizado.

Referencias