In this tutorial, we are going to see one of the distinctive features of jinja templates called jinja template inheritance.

Jinja template inheritance:

The idea of template inheritance is that we are going to design a base template that contains all the common features that belong to all the pages, and then we are going to provide the content specific to each page in a derived template.


  • Python 3.8.5
  • Flask 2.0.1

Jinja template inheritance Example:

As part of this example, I am going to implement a header bar, obviously, we want this header bar to appear on all the pages of our application.

Application Structure:

(venv) flask-jinja-inheritance %
├── app
│   ├──
│   ├──
│   └── templates
│       ├── header.html
│       ├── index.html
│       └── profile.html

Creating generic header page

Here I would like to implement the header page in a way that can integrate every template that I want. Usually, the header should be present on all the pages in the application.


        <title>My Blog</title>
    <h2 style="color:#093657">My Blog</h2> <a href="/">Home</a> | <a href="/profile">Profile</a>
        {% block content %} {% endblock %}

On the above, I created a simple header portion with the blog name, containing home and profile page links init, underneath that, created a new jinja construct called {% block content %} to specify the location where all the derived templates need to insert their page-specific content.

Now I have a pretty generic header page, that I can use all for my pages, now I need to prepare index and profile templates by extending this.

Preparing index.html with a simple welcome message.

{% extends "header.html" %}

{% block content %}
<h1 style="color:#093657"> Welcome
    {% if user %}
    {% else %}
    {% endif %}
{% endblock %}

The way I am linking this index template with the header template is through the extends construct {% extends "header.html"%} and then I provided the content that specific to this page in block content {% block content %} is the same name which we specified in the header template.

Now let’s prepare the profile page with some more information about the user.


{% extends "header.html" %}

{% block content %}
        {% for hobby in profile.hobbies %}
        {% endfor %}
Interested Books:
        {% for key in profile.interested_books %}
            {% for book in profile.interested_books.get(key)%}
            {% endfor %}
        {% endfor %}
{% endblock %}


from app import app
from flask import render_template

def index():
    user_info = {
    return render_template('index.html', user=user_info)

def profile():
    user = {
        'name': 'Chandra'
    profile = {
        'hobbies':['Blogging','Reading Books','Playing chess'],
            'Java':['Thinking in Java','Inside the Java virtual machine'],
            'Python':['Fluent Python']
    return render_template('profile.html', user=user, profile=profile)

On the above I have two routes representing index.html and profile.html

When I pass the index.html or profile.html to the render_template() function it’s going to find that there is a reference to a base template (header template) so that it’s going render the header template in the place where the empty block content {% block content %} {% endblock %} and it’s going to put the contents that we have in the profile/index pages.

Now let’s try run this:

Flask - Jinja Template inheritance Example home

There you can see our header section and home page content. Now try access Profile page

Flask - Jinja Template inheritance Example profile



Happy Learning 🙂