• Overview | ||
• List of tags | ||
• Custom tags | ||
Next: List of tags, Up: Tags [Contents][Index]
Tags look like this: {% tag %}
. Tags are more complex than variables: Some
create text in the output, some control flow by performing loops or logic, and
some load external information into the template to be used by later variables.
Some tags require beginning and ending tags (i.e. {% tag %} ... tag contents
... {% endtag %}
).
Here are some of the more commonly used tags:
for
Loop over each item in an array. For example, to display a list of athletes
provided in athlete-list
:
<ul> {% for athlete in athlete-list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
if
, else
Evaluates a variable, and if that variable is “true” the contents of the block are displayed:
{% if athlete-list %} Number of athletes: {{ athlete-list|length }} {% else %} No athletes. {% endif %}
block
and extends
Set up template inheritance (see below), a powerful way of cutting down on “boilerplate” in templates.
Next: Custom tags, Previous: Overview, Up: Tags [Contents][Index]
• block | ||
• extends | ||
• super | ||
• comment | ||
• cycle | ||
• debug | ||
• filter | ||
• firstof | ||
• for | ||
• if | ||
• Boolean operators | ||
• ifchanged | ||
• ifequal | ||
• ifnotequal | ||
• include | ||
Next: extends, Up: List of tags [Contents][Index]
Defines a block that can be overridden by child templates.
Sample usage:
{% block stylesheets %} ... {% endblock %}
See Template inheritance for more information.
Next: super, Previous: block, Up: List of tags [Contents][Index]
Extends a template
Sample usage:
{% extends "base.html" %}
Next: comment, Previous: extends, Up: List of tags [Contents][Index]
Gets the content of the block from the parent template. You can pass the name of the block of the parent block you want to access. If no name is passed, then the current block’s parent is used.
Sample usage:
{% super "stylesheets" %} {% block stylesheets %} {% super %} {% endblock %}
Next: cycle, Previous: super, Up: List of tags [Contents][Index]
Ignores everything between {% comment %}
and {% endcomment %}
.
An optional note may be inserted in the first tag. For example, this is
useful when commenting out code for documenting why the code was disabled.
Sample usage:
<p>Rendered text with {{ pub-date|date }}</p> {% comment "Optional note" %} <p>Commented out text with {{ create-date|date }}</p> {% endcomment %}
comment
tags cannot be nested.
Next: debug, Previous: comment, Up: List of tags [Contents][Index]
Produces one of its arguments each time this tag is encountered. The first argument is produced on the first encounter, the second argument on the second encounter, and so forth. Once all arguments are exhausted, the tag cycles to the first argument and produces it again.
This tag is particularly useful in a loop:
{% for o in some-list %} <tr class="{% cycle "row1" "row2" %}"> ... </tr> {% endfor %}
The first iteration produces HTML that refers to class row1
, the second to
row2
, the third to row1
again, and so on for each iteration of the
loop.
You can use variables, too. For example, if you have two template variables,
rowvalue1
and rowvalue2
, you can alternate between their values like
this:
{% for o in some-list %} <tr class="{% cycle rowvalue1 rowvalue2 %}"> ... </tr> {% endfor %}
You can mix variables and strings:
{% for o in some-list %} <tr class="{% cycle "row1" rowvalue2 "row3" %}"> ... </tr> {% endfor %}
You can use any number of values in a cycle
tag, separated by spaces.
Values enclosed in double quotes ("
) are treated
as string literals, while values without quotes are treated as template
variables.
Next: filter, Previous: cycle, Up: List of tags [Contents][Index]
Outputs a whole load of debugging information
Next: firstof, Previous: debug, Up: List of tags [Contents][Index]
Filters the contents of the block through one or more filters. Multiple filters can be specified with pipes and filters can have arguments, just as in variable syntax.
Note that the block includes all the text between the filter
and
endfilter
tags.
Sample usage:
{% filter force-escape|lower %} This text will be HTML-escaped, and will appear in all lowercase. {% endfilter %}
|
Next: for, Previous: filter, Up: List of tags [Contents][Index]
Outputs the first argument variable that is not False
. Outputs nothing if
all the passed variables are False
.
Sample usage:
{% firstof var1 var2 var3 %}
You can also use a literal string as a fallback value in case all passed variables are False:
{% firstof var1 var2 var3 "fallback value" %}
Next: if, Previous: firstof, Up: List of tags [Contents][Index]
Loops over each item in an array, making the item available in a context
variable. For example, to display a list of athletes provided in
athlete-list
:
<ul> {% for athlete in athlete-list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
If you need to loop over an association list, you can unpack the values
in each sublist into individual variables. For example, if your context
contains a list of (x . y) coordinates called points
, you could use the
following to output the list of points:
{% for (x . y) in points %} There is a point at {{ x }},{{ y }} {% endfor %}
This can also be useful if you need to access the items in a hash-table.
For example, if your context contained a hash-table named data
, the following
would display the keys and values of the hash-table:
{% for (key . value) in data.items %} {{ key }}: {{ value }} {% endfor %}
If you need to loop a fixed number of times, you can use the following trick, where data.nb
resolves to an integer:
{% for _ in data.nb.make-list %} index: {{ forloop.counter }} {% endfor %}
The _
is not meaningful, it is only a placeholder for a value that we can’t reuse (it’s nil). See also the djula::iterable-list
generic method.
The for loop sets a number of variables available within the loop:
Variable | Description |
---|---|
forloop.counter | The current iteration of the loop (1-indexed) |
forloop.counter0 | The current iteration of the loop (0-indexed) |
forloop.revcounter | The number of iterations from the end of the loop (1-indexed) |
forloop.revcounter0 | The number of iterations from the end of the loop (0-indexed) |
forloop.first | True if this is the first time through the loop |
forloop.last | True if this is the last time through the loop |
forloop.parentloop | For nested loops, this is the loop surrounding the current one |
Next: Boolean operators, Previous: for, Up: List of tags [Contents][Index]
The {% if %}
tag evaluates a variable, and if that variable is “true” (i.e.
exists, is not empty, and is not a false boolean value) the contents of the
block are output:
{% if athlete-list %} Number of athletes: {{ athlete-list|length }} {% else %} No athletes. {% endif %}
In the above, if athlete-list
is not empty, the number of athletes will be
displayed by the {{ athlete-list|length }}
variable.
For multiple branches, elif
and else
can be used:
{% if kenny.sick %} Kenny is sick. {% elif kenny.dead %} You killed Kenny! You bastard!!! {% else %} Kenny looks okay --- so far {% endif %}
Next: ifchanged, Previous: if, Up: List of tags [Contents][Index]
if
tags may use and
, or
or not
to test a number of
variables or to negate a given variable:
{% if athlete-list and coach-list %} Both athletes and coaches are available. {% endif %} {% if not athlete-list %} There are no athletes. {% endif %} {% if athlete-list or coach-list %} There are some athletes or some coaches. {% endif %} {% if not athlete-list or coach-list %} There are no athletes or there are some coaches (OK, so writing English translations of boolean logic sounds stupid; it's not our fault). {% endif %} {% if athlete-list and not coach-list %} There are some athletes and absolutely no coaches. {% endif %}
Use of both and
and or
clauses within the same tag is allowed, with
and
having higher precedence than or
e.g.:
{% if athlete-list and coach-list or cheerleader-list %}
will be interpreted like:
(if (or (athlete-list and coach-list) cheerleader-list) ..)
Use of actual parentheses in the if
tag is invalid syntax. If you need
them to indicate precedence, you should use nested if
tags.
Next: ifequal, Previous: Boolean operators, Up: List of tags [Contents][Index]
Check if a value has changed from the last iteration of a loop.
The {% ifchanged %}
block tag is used within a loop.
If given one or more variables, check whether any variable has changed.
For example, the following shows the date every time it changes, while showing the hour if either the hour or the date has changed:
{% for date in days %} {% ifchanged date.date %} {{ date.date }} {% endifchanged %} {% ifchanged date.hour date.date %} {{ date.hour }} {% endifchanged %} {% endfor %}
The ifchanged
tag can also take an optional {% else %}
clause that
will be displayed if the value has not changed:
{% for match in matches %} <div style="background-color: {% ifchanged match.ballot-id %} {% cycle "red" "blue" %} {% else %} gray {% endifchanged %} ">{{ match }}</div> {% endfor %}
Next: ifnotequal, Previous: ifchanged, Up: List of tags [Contents][Index]
Output the contents of the block if the two arguments equal each other.
Example:
{% ifequal user.pk comment.user-id %} ... {% endifequal %}
As in the if
tag, an {% else %}
clause is optional.
The arguments can be hard-coded strings, so the following is valid:
{% ifequal user.username "adrian" %} ... {% endifequal %}
An alternative to the ifequal
tag is to use the if
tag and the
==
operator.
Next: include, Previous: ifequal, Up: List of tags [Contents][Index]
Just like ifequal
, except it tests that the two arguments are not
equal.
An alternative to the ifnotequal
tag is to use the if
and
the !=
operator.
Previous: ifnotequal, Up: List of tags [Contents][Index]
Loads a template and renders it with the current context. This is a way of “including” other templates within a template.
The template name can either be a variable or a hard-coded (quoted) string, in either single or double quotes.
This example includes the contents of the template "foo/bar.html"
:
{% include "foo/bar.html" %}
A set of parameters can also be added, which become available as context variables when the included template is rendered:
{% include "user.html" :user record.creator %} {% include "user.html" :user record.updater %}
Previous: List of tags, Up: Tags [Contents][Index]
TODO
Previous: List of tags, Up: Tags [Contents][Index]