Jinja2 Templating in Flask

Loading

Jinja2 is the default templating engine used in Flask for rendering dynamic HTML content. It allows embedding Python-like expressions inside HTML, enabling developers to create dynamic and reusable templates. Jinja2 helps in separating the presentation layer from the application logic, making web applications more maintainable.


1. Setting Up Jinja2 in Flask

To use Jinja2, you need a templates folder inside your Flask project. Flask automatically looks for HTML templates in this directory.

Folder Structure

/flask_app
/templates
index.html
about.html
app.py

Basic Flask Application with Jinja2

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def home():
return render_template("index.html", name="John Doe")

if __name__ == "__main__":
app.run(debug=True)

This code sends the variable name to the template index.html.


2. Jinja2 Syntax

Jinja2 syntax allows us to use expressions, loops, conditionals, and filters inside HTML.

2.1 Variables

Inside templates, variables are enclosed in {{ }}:

<h1>Welcome, {{ name }}!</h1>

If name = "John Doe", the rendered output will be:

<h1>Welcome, John Doe!</h1>

2.2 Control Structures

2.2.1 If-Else Conditions

{% if age >= 18 %}
<p>You are eligible to vote.</p>
{% else %}
<p>You are not eligible to vote.</p>
{% endif %}

2.2.2 For Loops

<ul>
{% for user in users %}
<li>{{ user }}</li>
{% endfor %}
</ul>

If users = ["Alice", "Bob", "Charlie"], it will generate:

<ul>
<li>Alice</li>
<li>Bob</li>
<li>Charlie</li>
</ul>

3. Jinja2 Filters

Jinja2 filters modify variables in templates.

3.1 Common Filters

FilterDescriptionExample
upperConverts to uppercase`{{ name
lowerConverts to lowercase`{{ name
titleCapitalizes words`{{ name
lengthReturns length`{{ users
defaultSets default value`{{ age

Example: Using Filters

<p>{{ name|upper }}</p>
<p>Number of users: {{ users|length }}</p>

4. Template Inheritance

Jinja2 allows defining a base template and extending it in other templates.

4.1 Creating a Base Template

templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Flask App{% endblock %}</title>
</head>
<body>
<header>
<h1>My Website</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>

4.2 Extending the Base Template

templates/index.html

{% extends "base.html" %}

{% block title %}Home - Flask App{% endblock %}

{% block content %}
<h2>Welcome to My Flask App</h2>
{% endblock %}

5. Including and Reusing Templates

Instead of repeating code, we can include parts of a template.

5.1 Creating a Navbar Component

templates/navbar.html

<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>

5.2 Including the Navbar in Other Templates

{% include "navbar.html" %}

6. Passing Data from Flask to Jinja2

6.1 Passing Lists

@app.route("/users")
def users():
user_list = ["Alice", "Bob", "Charlie"]
return render_template("users.html", users=user_list)

users.html

<ul>
{% for user in users %}
<li>{{ user }}</li>
{% endfor %}
</ul>

6.2 Passing Dictionaries

@app.route("/profile")
def profile():
user_info = {"name": "John Doe", "age": 25, "city": "New York"}
return render_template("profile.html", user=user_info)

profile.html

<p>Name: {{ user.name }}</p>
<p>Age: {{ user.age }}</p>
<p>City: {{ user.city }}</p>

7. Using Macros in Jinja2

Macros allow reusable template components.

7.1 Creating a Macro

templates/macros.html

{% macro button(text, link) %}
<a href="{{ link }}" class="btn">{{ text }}</a>
{% endmacro %}

7.2 Using the Macro

{% import "macros.html" as macros %}

{{ macros.button("Click Here", "/about") }}

8. Static Files in Jinja2 (CSS & JS)

Flask serves static files from the /static folder.

8.1 Folder Structure

/flask_app
/static
/css
style.css
/js
script.js
/templates
index.html
app.py

8.2 Linking CSS and JavaScript

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/script.js') }}"></script>

9. Escaping HTML in Jinja2

Jinja2 automatically escapes special HTML characters to prevent XSS attacks.

Example

<p>{{ "<script>alert('XSS')</script>" }}</p>

Rendered output:

<p>&lt;script&gt;alert('XSS')&lt;/script&gt;</p>

To disable escaping:

<p>{{ "<script>alert('XSS')</script>" | safe }}</p>

10. Debugging in Jinja2

10.1 Showing Debug Information

If a variable is None, use:

{{ variable or "Default Value" }}

10.2 Using {% set %}

{% set greeting = "Hello, World!" %}
<p>{{ greeting }}</p>

Leave a Reply

Your email address will not be published. Required fields are marked *