Create reusable Jinja templates
Templates tend to have common sections that are equally used across multiple instances. For example, the header and footer sections on all templates rarely changes, whether a project has five or one hundred templates. Other template sections like menus and advertisements, also fall into this category of content that's constant across multiple templates. All of this can lead to repetition over multiple templates, which can be avoided by creating reusable templates.
With reusable Jinja templates you can define common sections on separate templates and reuse them inside other templates. This process makes it easy to create and manage a project's templates because a single template update takes effect on all templates.
Reusable Jinja templates also allow you to define page blocks to override content on a page by page basis. This process makes a project's templates more modular because you define top level blocks to establish the overall layout and define content on a page by page basis.
Lets take the first step toward
building reusable Jinja templates by exploring Jinja's built-in
{% block %}
tag. Listing 4-5 illustrates the first
lines of a template called base.html
with several
{% block %}
tags.
Listing 4-5. Jinja template with {% block %} tags
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>{% block title%}Default title{% endblock title %}</title> <meta name="description" content="{% block metadescription%}{% endblock metadescription %}"> <meta name="keywords" content="{% block metakeywords%}{% endblock metakeywords %}">
Notice the syntax {% block
<name>%}{% endblock <name>%}
in listing 4-5.
Each {% block %}
tag has a reference name. The
reference name is used by other Jinja templates to override the
content for each block. For example, the {% block title
%}
tag within the HTML <title>
tags
defines a web page title. If another template reuses the template
in listing 4-5, it can define its own web page title by overriding
the title block. If a block is not overridden on a template, the
block receives the default content within the block. For the title
block the default content is Default title
, for the
metadescription
and metakeywords
blocks
the default content is an empty string.
The same mechanism illustrated in
listing 4-5 can be used to define any number of blocks (e.g.
content, menu, header, footer). It's worth mentioning the
<name>
argument of {% endblock
<name> %}
is optional and it's valid to just use
{% endblock %}
to close a block statement, however,
the former technique makes it clearer where a block statement ends
which is specially helpful when a template has multiple blocks.
Although it's possible to call
the template in listing 4-5 directly by a Django view method or url
request, the purpose of this kind of template is to use it as a
base template for other templates. To reuse a Jinja template you
use the Jinja built-in {% extends %}
tag.
The {% extends %}
tag uses the syntax {% extends <name> %}
to
reuse the layout of another template. This means that in order to
reuse the layout in listing 4-5 defined in a file
base.html
, you use the syntax {% extends
"base.html" %}
, as illustrated in listing 4-6.
Listing 4-6. Jinja template with {% extends %} and {% block %} tag
{% if user %}{% extends "base.html" %}{% else %}{% extends "signup_base.html" %}{% endif %} {% block title %}Coffeehouse home page{% endblock %}
Look how listing 4-6 uses the
{% extends "base.html" %}
wrapped around the {%
if user %}
statement. If the user
variable is
defined, Jinja extends the base.html
template,
otherwise it extends the signup_base.html
template.
This conditional syntax is not possible in Django templates.
The remaining content for Django 4.0 is only available with a subscription.