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 thenamevariable passed from the Flask view.{{ user.age }}accesses theagefield onuser(dict or object).render_templatetakes 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 Pythonifstatements.{% for item in items %}loops through a list and renders HTML for each element.{{ item.name }}outputs each item’snameattribute.
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 usebase.htmlas 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.