| ==================== |
| 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 %} |
| © 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. |