← Back to Chapters

Python Jinja2

? Python Jinja2 Templates

⚡ Quick Overview

Jinja2 is a modern, designer-friendly templating engine for Python. It lets you mix plain text (like HTML) with special template syntax to inject dynamic values, perform loops and conditionals, and reuse layouts.

  • Commonly used with web frameworks like Flask and Django (Django uses a similar engine).
  • Separates presentation (templates) from logic (Python code).
  • Can generate any kind of text: HTML, emails, config files, etc.

? Key Concepts

  • Template – text file with placeholders and logic.
  • Variables – values passed from Python into the template ({{ name }}).
  • Expressions – filters and operations used inside variables.
  • Statements – control flow with {% ... %} (if, for, block, extends).
  • Environment – Jinja2 configuration + loader that knows where to find templates.
  • Rendering – process of combining a template with data to produce final text.

? Syntax and Core Building Blocks

? Variables

Variables are written using double curly braces:

{{ variable_name }} or {{ user.name }}.

? Filters

Filters transform values and use the pipe syntax:

{{ name|upper }}, {{ items|length }}.

? Control Structures

  • If: {% if condition %} ... {% endif %}
  • For: {% for item in items %} ... {% endfor %}
  • Blocks: {% block content %} ... {% endblock %}
  • Inheritance: {% extends "base.html" %}

? Basic Standalone Jinja2 Example

You can use Jinja2 directly without a web framework by loading templates from the filesystem and rendering them.

? View Code Example (Standalone Jinja2)
from jinja2 import Environment, FileSystemLoader

# 1. Configure where templates live
env = Environment(loader=FileSystemLoader("templates"))

# 2. Load a template file from the templates/ directory
template = env.get_template("hello.html")

# 3. Data (context) to render inside the template
context = {
    "name": "Meghraj",
    "languages": ["Python", "JavaScript", "C++"],
}

# 4. Render final text output
output = template.render(context)

print(output)

? Expected Output / Explanation

This script looks for a file templates/hello.html, fills in all the placeholders using the context dictionary, and prints the final rendered text. You can then write this to a file, return it as an HTTP response, or send it as an email body.

? Template File Example (hello.html)

This is how the corresponding Jinja2 template might look inside templates/hello.html:

? View Code Example (Template Syntax)
# Jinja2 HTML template that renders a greeting page
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello Jinja2</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>

    <h2>Your favourite programming languages:</h2>
    <ul>
        {% for lang in languages %}
        <li>{{ lang }}</li>
        {% endfor %}
    </ul>

    <p>You know {{ languages|length }} languages in total.</p>
</body>
</html>

? Rendered HTML Snippet

For the given context, the core part of the rendered output would look like:

<h1>Hello, Meghraj!</h1>
A list of Python, JavaScript, C++, and a line saying You know 3 languages in total.

? Using Jinja2 with Flask

Flask integrates Jinja2 by default. You place templates in a templates/ folder and use render_template() to render them.

? View Code Example (Flask + Jinja2)
# Basic Flask application using Jinja2 templates
from flask import Flask, render_template

app = Flask(__name__)

# Route for the home page
@app.route("/")
def home():
    # Data passed into the Jinja2 template
    user = {
        "name": "Student",
        "is_admin": False,
        "skills": ["HTML", "CSS", "Python"]
    }
    return render_template("profile.html", user=user)

if __name__ == "__main__":
    # Enable debug mode only during development
    app.run(debug=True)

And the template templates/profile.html could use Jinja2 like this:

? View Code Example (profile.html)
# Jinja2 HTML template for a user profile page
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Profile</title>
</head>
<body>
    <h1>Welcome, {{ user.name }}!</h1>

    {% if user.is_admin %}
    <p>You have admin privileges.</p>
    {% else %}
    <p>You are a regular user.</p>
    {% endif %}

    <h2>Skills</h2>
    <ul>
        {% for skill in user.skills %}
        <li>{{ skill }}</li>
        {% endfor %}
    </ul>
</body>
</html>

? Live Output / Explanation

When you visit http://localhost:5000/, Flask passes the user dictionary into profile.html. Jinja2 uses the values to decide which paragraph to show (admin vs regular user), and creates a list of skills dynamically.

? Useful Jinja2 Features

  • Template inheritance to create a common layout.
  • Includes to reuse partial templates (like headers/footers).
  • Built-in filters (upper, lower, length, safe, etc.).
  • Custom filters written in Python and registered in the environment or Flask app.
? View Code Example (Template Inheritance)
# Base layout template for the site
{# base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
    <header>
        <h1>My Site</h1>
    </header>

    <main>
        {% block content %}{% endblock %}
    </main>

    <footer>
        <p>&copy; {{ 2025 }} My Site</p>
    </footer>
</body>
</html>
? View Code Example (Child Template)
# Child template that extends base.html and fills in content
{% extends "base.html" %}

{% block title %}Home{% endblock %}

{% block content %}
<h2>Home page</h2>
<p>This page uses the base layout and fills in its own content block.</p>
{% endblock %}

? Tips & Best Practices

  • Keep heavy business logic in Python, not inside templates.
  • Use template inheritance to avoid copy-pasting the same HTML structure.
  • Group templates in folders (e.g., auth/login.html) for larger projects.
  • Be careful with user input – use auto-escaping (enabled by default in Flask for HTML).
  • Use filters to format values (dates, currency) instead of manually concatenating strings.

? Practice Tasks

  1. Create a standalone Jinja2 script that renders a simple HTML page with your name and a list of 3 favourite movies.
  2. Build a base.html with a header and footer, then create two child templates: home.html and about.html that extend the base.
  3. In a Flask app, create a route /products that passes a list of product dictionaries (name, price, in_stock) to a template and displays them in a table.
  4. Define a custom Jinja2 filter (in Flask or plain Jinja2) to format a price as ₹1,234.00 and use it in your template.

? When to Use Jinja2

  • You need to generate HTML pages or emails from Python.
  • You want to keep templates designer-friendly and separate from backend logic.
  • You are using Flask or another framework that supports Jinja2.
  • You need reusable layouts and components in your views.