7 minutes read

Usually, a web application's web pages has similar components: headers, footers, navigation bars, and so on. In other words, parts that will not change on different pages. We can take advantage of this fact and write shorter, reusable templates using Jinja template inheritance property.

What is template inheritance?

Template inheritance enables us to build a parent "skeleton" template that will contain similar components and elements together with shorter, easy-to-manage child templates.

Every time you create a web page, instead of adding common elements, such as main html tags, headers, and footers, you can use a base template instead. It allows other pages to inherit these elements. Take a look at a folder structure:

application/
├── app.py
└── templates/
    ├── base.html
    ├── home.html
    ├── about.html

Flask looks for templates in the templates directory.

Our website will have two static pages about Radiohead. One contains a list of all their albums, and another contains information about the band.

Run.py is a very basic flask application:

from flask import Flask, render_template
  
# Setting up the application
app = Flask(__name__)
  

@app.route('/')
@app.route('/home')
def home():
    return render_template('home.html')
@app.route('/about')
def about():
    return render_template('about.html')
  

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

And now, the base template:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>{% block title %}{% endblock %} | Radiohead</title> 
 <! -- we used the same name for the block as the name tag (title) -->
</head>
<body>
  <header>
    <nav> <a href="#">Menu</a> 
      <a href="#"> Radiohead</a>
    </nav> 
  </header>
    <main>
    <div id = "content">
    {% block content %}{% endblock %}
    </div>
    <div id = "container2">
    {% block container2 %}{% endblock %}
    </div>
    </main>
    <footer>
    {% block footer %} &copy;Copyright 2022 by Me {% endblock %}
    </footer>

</body>
</html>

This will be our parent template.

  • We have a dummy navigation bar with two texts (Menu, Radiohead) that will be common to both the home and about pages;

  • {% block % } {% endblock %} defines the block that will be filled by the child templates. You don't need to write any other content besides the blocks in these child HTML files. Everything else will be inherited from this parent skeleton;

  • The name of the block is written after the initial {% block %}. We recommend naming this block the same as the immediate tag or id it is found under.

Linking templates

How do we link the child templates with the parent ones? With {% extends %} in the child templates:

{% extends "base/parent_template.html" %}

We can put {% extends %} into any child template; it is followed by the name of the base/parent template in " ". Afterwards, Jinja will use the base template and load the {% block % } {% endblock %} from it into the child template.

Here is the templates/home.html:


{% extends "base.html" %}

{% block title %} Album {% endblock %}


{% block content %}
    <h3> Albums by the best band in the world</h3>
{% endblock %}


{% block container2 %}
<ul>
    <li>Pablo Honey</li>   <li>The Bends</li>
    <li>Ok Computer</li>   <li>Kid A</li>
    <li>Amnesia</li>       <li>Hail to the Thief</li>
    <li>In Rainbows</li>   <li>The King of Limbs</li>
    <li>A Moon Shaped Pool</li>
</ul> 
{% endblock %}

{% block footer %}
@ Radiohead
{% endblock %}

And templates/about.html:

{% extends "base.html" %}
{% block title %} About{% endblock %}

{% block content %}
<h1>About Radiohead</h1>
{% endblock %}


{% block container2 %}
Simply put they are the best. (for me)
{% endblock %}

As simple as that. No more writing <html> </html>, ⁣<head> </head> or the same navigation bar for each page. Similarly, if you have a component you want to multiply, state it once in the parent template, and then just {% extends %} it.

Here is the result for the example above:

example templates/home.htmlexample templates/about.html

Conclusion

In this topic, we've discussed several things:

  • Template inheritance will reduce the amount of HTML and increase the maintainability of your components;

  • In the above example, since the about template didn't define the footer block, the value from the parent base template is used instead;

  • You can simply use {% extends 'base_template' %} to connect the parent template with the child template, where base_template is the location of the base.html file;

  • Use {% block 'name of block' %} {% endblock %} on the base template for parts that will vary from page to page, where name of block is the name in the child template. Usually, it's the ID name or the tag of the container.

12 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo