Jinja

Template Inheritance

Navigation

Contents

The most powerful part of Jinja is template inheritance. Template inheritance allows you to build a base "skeleton" template that contains all the common elements of your site and defines blocks that child templates can override.

Sounds complicated but is very basic. It's easiest to understand it by starting with an example.

Base Template

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <link rel="stylesheet" href="style.css" />
  <title>{% block title %}{% endblock %} - My Webpage</title>
  {% block html_head %}{% endblock %}
</head>
<body>
  <div id="content">
    {% block content %}{% endblock %}
  </div>

  <div id="footer">
    {% block footer %}
    &copy; Copyright 2006 by <a href="http://mydomain.tld">myself</a>.
    {% endblock %}
  </div>
</body>

In this example, the {% block %} tags define four blocks that child templates can fill in. All the block tag does is to tell the template engine that a child template may override those portions of the template.

Child Template

A child template might look like this:

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

{% block html_head %}
  <style type="text/css">
    .important {
      color: #336699;
    }
  </style>
{% endblock %}

{% block content %}
    <h1>Index</h1>
    <p class="important">
      Welcome on my awsome homepage.
    </p>
{% endblock %}

The {% extends %} tag is the key here. It tells the template engine that this template "extends" another template. When the template system evaluates this template, first it locates the parent. It must be always the first tag in a template but whitespace or a comment is allowed before. This was not enforced with Jinja 1.0 and 1.1, it does however raise a syntax error with 1.2 or later.

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

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

But this behavior can depend on the application using Jinja.

Note that since the child template didn't define the footer block, the value from the parent template is used instead.

Note

You can't define multiple {% block %} tags with the same name in the same template. This limitation exists because a block tag works in "both" directions. That is, a block tag doesn't just provide a hole to fill - it also defines the content that fills the hole 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.

How Inheritance Works Internally

Inheritance in Jinja is straightforward. If a template contains an {% extends %} tag it's considered being a child template, otherwise it's a layout template. In a layout template you can place blocks basically everywhere. In a child template blocks can only be located either at the top level or inside another block.

Data outside of a block in a child template is executed before the layout template is rendered, thus you can use it to propagate data to the whole inheritance chain. Having a block in an invalid position you will receive an syntax error. Here some examples:

impossible:

{% extends 'master.html' %}
{% if some_condition %}
  {% block body %}
    ...
  {% endblock %}
{% endif %}

This can't work because template inheritance works at translation / compilation time not at template execution.

possible:

{% extends 'master.html' %}
{% block body %}
  {% if some_condition %}
    {% block myblock %}
      ...
    {% endblock %}
  {% endif %}
{% endblock %}

This can work although it probably makes no sense in this specific case. However the condition is handled at runtime because it's in a valid block and defines a new block subtemplates can override.

Note

Unlike Python Jinja does not support multiple inheritance. So you can only have one extends tag with only one constant string argument.

Super Blocks

Starting with Jinja 1.1 it's possible to render the contents of the parent block. By calling it you get the results of the parent block back. If you want to get the data of the parent you can give it an offset:

{{ super() }}
    return the parent data

{{ super(1) }}
    the same as above

{{ super(2) }}
    return the data of the second parent block

Block Shortcuts

With Jinja 1.1 onwards it's possible to have a shortcut syntax for blocks with few content. The following constructs do the same:

{% block title %}{{ page_title }}{% endblock %}

{% block title page_title %}

Note that as soon as you specify a second argument it's threated as short block and Jinja won't look for an closing tag.