Python Template Engines — Jinja2 & String Templates

Python AdvancedTemplatesFree Lesson

Advertisement

Python Template Engines — Jinja2 & String Templates

Templating generates dynamic text from templates with variable substitution and logic. Essential for HTML generation, email templates, and configuration files.

Learning Objectives

  • Use Python's string.Template for simple substitution
  • Master Jinja2 for complex templating
  • Apply template inheritance for reusable layouts
  • Generate HTML and documents from templates

string.Template (Standard Library)

from string import Template

# Simple substitution
template = Template("Hello, $name! Your balance is $${amount}.")
result = template.substitute(name="Alice", amount=1000)
print(result)  # Hello, Alice! Your balance is $1000.

# Safe substitution (no error on missing keys)
result = template.safe_substitute(name="Bob")
print(result)  # Hello, Bob! Your balance is $${amount}.

Jinja2 Basics

from jinja2 import Template

# Simple variable substitution
template = Template("Hello, {{ name }}!")
print(template.render(name="Alice"))

# Filters
template = Template("{{ name | upper }}")
print(template.render(name="alice"))  # ALICE

# Control flow
template = Template("""
{% for item in items %}
  - {{ item }}
{% endfor %}
""")
print(template.render(items=["Apple", "Banana", "Cherry"]))

# Conditions
template = Template("""
{% if score >= 90 %}
  Grade: A
{% elif score >= 80 %}
  Grade: B
{% else %}
  Grade: C
{% endif %}
""")

Template Inheritance

from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('templates'))

# base.html — the parent template
"""
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
    <nav>{% block nav %}{% endblock %}</nav>
    <main>{% block content %}{% endblock %}</main>
    <footer>{% block footer %}Default Footer{% endblock %}</footer>
</body>
</html>
"""

# page.html — extends base
"""
{% extends "base.html" %}
{% block title %}{{ page_title }}{% endblock %}
{% block nav %}
  <a href="/">Home</a>
  <a href="/about">About</a>
{% endblock %}
{% block content %}
  <h1>{{ heading }}</h1>
  <p>{{ body }}</p>
{% endblock %}
"""

Generating HTML Reports

from jinja2 import Template

report_template = Template("""
<html>
<head><title>Sales Report</title></head>
<body>
  <h1>Sales Report — {{ period }}</h1>
  <table border="1">
    <tr><th>Product</th><th>Units</th><th>Revenue</th></tr>
    {% for product in products %}
    <tr>
      <td>{{ product.name }}</td>
      <td>{{ product.units }}</td>
      <td>${{ "%.2f" | format(product.revenue) }}</td>
    </tr>
    {% endfor %}
  </table>
  <p><strong>Total Revenue:</strong> ${{ "%.2f" | format(total_revenue) }}</p>
</body>
</html>
""")

html = report_template.render(
    period="January 2024",
    products=[
        {"name": "Widget A", "units": 150, "revenue": 4500.00},
        {"name": "Widget B", "units": 80, "revenue": 3200.00},
    ],
    total_revenue=7700.00
)

Key Takeaways

  1. Use string.Template for simple substitution (no dependencies)
  2. Use Jinja2 for complex HTML/document generation
  3. Template inheritance reduces duplication
  4. Auto-escaping prevents XSS in HTML
  5. Use |safe to disable escaping for trusted HTML
  6. Filters transform variables in templates
  7. Macros are reusable template components

Advertisement

Need Expert Python Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement