blob: d9d0cdc17e8d5d09bb6f87f2bd903e76d6cf3251 [file] [log] [blame]
====================
Template Inheritance
====================
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:
.. sourcecode:: html+jinja
<!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:
.. sourcecode:: html+jinja
{% 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:
.. sourcecode:: jinja
{% 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.
.. admonition:: 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**:
.. sourcecode:: jinja
{% 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**:
.. sourcecode:: jinja
{% 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.
.. admonition:: 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:
.. sourcecode:: jinja
{{ 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:
.. sourcecode:: jinja
{% 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.