Template Inheritance

The most powerful part of Jinja is template inheritance. Template inheritanceallows you to build a base “skeleton” template that contains all the commonelements of your site and defines blocks that child templates can override.

Sounds complicated but is very basic. It’s easiest to understand it by startingwith an example.

Base Template

This template, which we’ll call base.html, defines a simple HTML skeletondocument that you might use for a simple two-column page. It’s the job of“child” templates to fill the empty blocks with content:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. {% block head %}
  5. <link rel="stylesheet" href="style.css" />
  6. <title>{% block title %}{% endblock %} - My Webpage</title>
  7. {% endblock %}
  8. </head>
  9. <body>
  10. <div id="content">{% block content %}{% endblock %}</div>
  11. <div id="footer">
  12. {% block footer %}
  13. &copy; Copyright 2008 by <a href="http://domain.invalid/">you</a>.
  14. {% endblock %}
  15. </div>
  16. </body>
  17. </html>

In this example, the {% block %} tags define four blocks that child templatescan fill in. All the block tag does is tell the template engine that achild template may override those placeholders in the template.

Child Template

A child template might look like this:

  1. {% extends "base.html" %}
  2. {% block title %}Index{% endblock %}
  3. {% block head %}
  4. {{ super() }}
  5. <style type="text/css">
  6. .important { color: #336699; }
  7. </style>
  8. {% endblock %}
  9. {% block content %}
  10. <h1>Index</h1>
  11. <p class="important">
  12. Welcome to my awesome homepage.
  13. </p>
  14. {% endblock %}

The {% extends %} tag is the key here. It tells the template engine thatthis template “extends” another template. When the template system evaluatesthis template, it first locates the parent. The extends tag should be thefirst tag in the template. Everything before it is printed out normally andmay cause confusion. For details about this behavior and how to takeadvantage of it, see Null-Master Fallback. Also a block will always befilled in regardless of whether the surrounding condition is evaluated to be trueor false.

The filename of the template depends on the template loader. For example, theFileSystemLoader allows you to access other templates by giving thefilename. You can access templates in subdirectories with a slash:

  1. {% extends "layout/default.html" %}

But this behavior can depend on the application embedding Jinja. Note thatsince the child template doesn’t define the footer block, the value fromthe parent template is used instead.

You can’t define multiple {% block %} tags with the same name in thesame template. This limitation exists because a block tag works in “both”directions. That is, a block tag doesn’t just provide a placeholder to fill- it also defines the content that fills the placeholder in the parent.If there were two similarly-named {% block %} tags in a template,that template’s parent wouldn’t know which one of the blocks’ content to use.

If you want to print a block multiple times, you can, however, use the specialself variable and call the block with that name:

  1. <title>{% block title %}{% endblock %}</title>
  2. <h1>{{ self.title() }}</h1>
  3. {% block body %}{% endblock %}

Super Blocks

It’s possible to render the contents of the parent block by calling super.This gives back the results of the parent block:

  1. {% block sidebar %}
  2. <h3>Table Of Contents</h3>
  3. ...
  4. {{ super() }}
  5. {% endblock %}

Named Block End-Tags

Jinja2 allows you to put the name of the block after the end tag for betterreadability:

  1. {% block sidebar %}
  2. {% block inner_sidebar %}
  3. ...
  4. {% endblock inner_sidebar %}
  5. {% endblock sidebar %}

However, the name after the endblock word must match the block name.

Block Nesting and Scope

Blocks can be nested for more complex layouts. However, per default blocksmay not access variables from outer scopes:

  1. {% for item in seq %}
  2. <li>{% block loop_item %}{{ item }}{% endblock %}</li>
  3. {% endfor %}

This example would output empty <li> items because item is unavailableinside the block. The reason for this is that if the block is replaced bya child template, a variable would appear that was not defined in the block orpassed to the context.

Starting with Jinja 2.2, you can explicitly specify that variables areavailable in a block by setting the block to “scoped” by adding the _scoped_modifier to a block declaration:

  1. {% for item in seq %}
  2. <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li>
  3. {% endfor %}

When overriding a block, the scoped modifier does not have to be provided.

Template Objects

Changelog

Changed in version 2.4.

If a template object was passed in the template context, you canextend from that object as well. Assuming the calling code passesa layout template as layout_template to the environment, thiscode works:

  1. {% extends layout_template %}

Previously, the layout_template variable had to be a string withthe layout template’s filename for this to work.