Common Jinja2 Examples
Here are practical patterns you'll use frequently when building templates.
Invoice with line items
{
"invoice_number": "INV-2026-001",
"customer": "Acme Corp",
"items": [
{"description": "Web Design", "hours": 40, "rate": 75},
{"description": "Development", "hours": 80, "rate": 100},
{"description": "QA Testing", "hours": 20, "rate": 60}
],
"tax_rate": 0.1
}
<h1>Invoice {{invoice_number}}</h1>
<p>Bill to: {{customer}}</p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Hours</th>
<th>Rate</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td>{{item.description}}</td>
<td>{{item.hours}}</td>
<td>${{"${:,.2f}".format(item.rate)}}</td>
<td>${{"${:,.2f}".format(item.hours * item.rate)}}</td>
</tr>
{% endfor %}
</tbody>
</table>
Conditional status badges
{
"status": "paid",
"amount": 1500
}
{% if status == "paid" %}
<span style="color: green; font-weight: bold;">PAID</span>
{% elif status == "pending" %}
<span style="color: orange; font-weight: bold;">PENDING</span>
{% else %}
<span style="color: red; font-weight: bold;">OVERDUE</span>
{% endif %}
Showing/hiding sections
{
"show_notes": true,
"notes": "Please pay within 30 days.",
"show_terms": false
}
{% if show_notes and notes %}
<div class="notes">
<h3>Notes</h3>
<p>{{notes}}</p>
</div>
{% endif %}
{% if show_terms %}
<div class="terms">
<h3>Terms and Conditions</h3>
<p>...</p>
</div>
{% endif %}
Alternating row colors
{% for item in items %}
<tr style="background: {% if loop.index is odd %}#f9f9f9{% else %}#ffffff{% endif %}">
<td>{{item.name}}</td>
<td>{{item.value}}</td>
</tr>
{% endfor %}
QR code on an invoice
{
"invoice_url": "https://example.com/invoices/INV-001",
"invoice_number": "INV-001"
}
<div style="text-align: center; margin-top: 20px;">
{{invoice_url | render_qrcode(style='width: 120px; height: 120px;')}}
<p>Scan to view invoice {{invoice_number}}</p>
</div>
Default values for missing data
<p>Company: {{ company_name | default("Not specified") }}</p>
<p>Phone: {{ phone | default("N/A") }}</p>
<p>Notes: {{ notes | default("No additional notes.") }}</p>
Formatting a list as a comma-separated string
{
"tags": ["urgent", "billing", "Q1"]
}
<p>Tags: {{ tags | join(", ") }}</p>
Output: Tags: urgent, billing, Q1
Date formatting in context
{
"created_at": "2026-03-28T10:30:00.000Z",
"due_date": "2026-04-28T10:30:00.000Z"
}
<p>Created: {{ strftime(strptime(created_at, "%Y-%m-%dT%H:%M:%S.%fZ"), "%B %d, %Y") }}</p>
<p>Due: {{ strftime(strptime(due_date, "%Y-%m-%dT%H:%M:%S.%fZ"), "%B %d, %Y") }}</p>
Output:
Created: March 28, 2026
Due: April 28, 2026
Next steps
- Debugging — troubleshooting template issues
- Default Filters — built-in Jinja2 filters
- APITemplate.io Filters — QR codes, barcodes, and tables