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 actualcompany: Información de la compañíaenvironment: 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.