Python Docs

Templates (Jinja2)

Jinja2 is a powerful templating engine used by Flask (and many other frameworks) to generate dynamic HTML. It lets you embed variables, control flow, inheritance, and filters directly inside your templates — while keeping Python logic in views and HTML in template files.

Variables

Use {{ }} to output variables in a Jinja2 template. You can access attributes and dictionary keys, just like in Python.

Example: Passing Variables from Flask to Jinja2

<!-- template.html -->
<h1>Hello {{ name }}!</h1>
<p>Age: {{ user.age }}</p>
# Flask view
from flask import render_template

@app.get('/hello/<name>')
def hello(name):
    user = {'age': 25}
    return render_template('template.html', name=name, user=user)

Key points:

  • {{ name }} prints the value of the name variable passed from the Flask view.
  • {{ user.age }} accesses the age field on user (dict or object).
  • render_template takes keyword arguments and exposes them inside the template context.

Control Flow

Jinja2 supports control structures like if and for using {% ... %} syntax.

Example: If / Else & Loops

{% if user.is_admin %}
  <p>Admin Panel</p>
{% else %}
  <p>User Dashboard</p>
{% endif %}

{% for item in items %}
  <li>{{ item.name }}</li>
{% endfor %}

How this works:

  • {% if ... %} / {% else %} / {% endif %} behave like Python if statements.
  • {% for item in items %} loops through a list and renders HTML for each element.
  • {{ item.name }} outputs each item’s name attribute.

Template Inheritance

Template inheritance lets you define a base layout and reuse it across multiple pages. This avoids repetition and keeps your HTML DRY (Don’t Repeat Yourself).

Example: base.html + page.html

<!-- base.html -->
<!DOCTYPE html>
<html>
<head><title>{% block title %}{% endblock %}</title></head>
<body>
  {% block content %}{% endblock %}
</body>
</html>

<!-- page.html -->
{% extends 'base.html' %}
{% block title %}Home{% endblock %}
{% block content %}<h1>Welcome</h1>{% endblock %}

Key ideas in inheritance:

  • {% extends 'base.html' %} tells Jinja2 to use base.html as the parent template.
  • {% block title %} and {% block content %} mark regions that child templates can override.
  • Ideal for layouts with a shared header, navbar, and footer.

Filters

Filters transform values in templates. Apply them using the | (pipe) operator.

Example: Common Filters

{{ name|upper }}           {# ALICE #}
{{ items|length }}        {# 5 #}
{{ price|round(2) }}      {# 19.99 #}

Examples of filter usage:

  • {{ name|upper }} → converts the string to uppercase.
  • {{ items|length }} → returns the count of items.
  • {{ price|round(2) }} → rounds a number to 2 decimal places.

Best Practices

  • Keep heavy business logic in Python, not in templates.
  • Use template inheritance for consistent layout.
  • Define custom filters in Python if built-in ones are not enough.
  • Avoid deeply nested control flow in templates to keep them readable.