liveBook · Manning

Jinja

As explained in The Well-Grounded Python Developer: How the pros use Python and Flask

Jinja2 is a Python template engine that renders text, including web pages, from templates containing static and dynamically generated content.

A web page often needs both fixed HTML and values that change on each request. Jinja2 lets a Flask application keep the HTML in a template file and supply the changing values when it renders the page. Think of a template as a document with placeholders: much as an f-string combines text with a Python value, Jinja2 combines page markup with data. The server fills those placeholders before sending the result to the browser. section 6.4.3

from flask import Flask, render_template                       #1
from datetime import datetime                                  #2
 
app = Flask(__name__)
 
@app.route("/")
def home():
    return render_template("index.html", now=datetime.now())   #3

The Flask route passes the current time as `now` to `index.html`; the template can place it in the page with `{{now}}`. Flask looks for that file in a `templates` directory. section 6.4.3

As a page grows, pass related values to the template and reuse a shared layout. A base template can hold the header, footer, and stylesheet link, while a page-specific template supplies its content. This keeps common markup in one place instead of repeating it across pages. section 6.4.4 section 6.7

{% extends "base.html" %}                                 #1
 
{% block content %}                                       #2
<h2>Current time: {{ data["now"] }}</h2>                  #2
<p>Page visits: {{ data["page_visit"].counts() }}</p>     #2
<p>List of available banner colors:</p>                   #2
<ul>                                                      #2
    {%                                                    #2
      for banner_color in                               #2
      data["banner_colors"]["display"]                  #2
      %}                                                #2
    <li>{{ banner_color }}</li>                           #2
    {% endfor %}                                          #2
</ul>                                                     #2
<div id="color-change">                                   #2
    <button class="change-banner-color">                  #2
        Change Banner Color                               #2
    </button>                                             #2
</div>                                                    #2
{% endblock %}                                            #2
 
{% block styles %}                                        #3
{{ super() }}                                             #3
<link                                                     #3
    rel="stylesheet"                                      #3
      type="text/css"                                   #3
      href="{{ url_for(                                 #3
          'static', filename='css/index.css'            #3
          ) }}">                                        #3
{% endblock %}                                            #3
 
{% block scripts %}                                       #4
{{ super() }}                                             #4
<script>                                                  #4
    const banner_colors =                                 #4
      {{ data["banner_colors"]["js"]| safe }};          #4
</script>                                                 #4
<script                                                   #4
      src="{{ url_for(                                  #4
          'static', filename='js/index.js') }}"         #4
></script>                                              #4
{% endblock %}                                            #4

The page template extends `base.html`, fills its content block, displays the current time and visit count, and uses a Jinja2 `for` loop to turn a supplied color list into HTML list items. section 6.4.4

Use Jinja2 for values the server must put into the delivered page. Those values might come from a calculation, a database, or another web service. CSS can style the result, and JavaScript can handle later interactions in the browser; neither replaces the server’s rendering step. section 6.4.3 section 6.4.4

How The Well-Grounded Python Developer: How the pros use Python and Flask covers it

How deep it goes
Works from a single placeholder through template inheritance and a loop, without exploring rendering internals.
Examples
Uses a current-time page, a visit counter, and a generated color list to illustrate placeholders and loops.
What it assumes
Assumes basic Python functions and HTML while introducing template placeholders through an f-string comparison.
What you can do after
Apply it via Flask’s `render_template` to build pages with dynamic values and a reusable layout.
How it connects
Connects Flask routes, HTML templates, template inheritance, CSS, JavaScript, and server-side rendering.

Also explained in

Compare how 4 books explain Jinja →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Python Developer: How the pros use Python and Flask. The section links point to the parts of the book it draws on.