Templates
We use PyPugJS (formerly Pyjade) as a Jinja extension.
Templates with the extension .j2.jade
or .j2.pug
are passed to PyPugJS and converted to a Jinja template.
Our templates mostly support the syntax of Pug which was called Jade before. Instead of Javascript, pieces of code in templates are interpreted as Jinja code. Keep that in mind when reading the language reference for Pug. As a basic rule, keep complicated logic away from templates and use Python code from the cell associated with a template. Reading existing templates and following their style is a good idea.
Code
Buffered (With Output)
=
is used to produce output from a Jinja expression. Pug calls this buffered code.
This works like {{ }}
in Jinja. For security, output is automatically escaped by Jinja.
p
= 'This code is <escaped>!'
For translations, gettext
with _
as alias and ngettext
from Babel are available in all templates.
Templates that are used by a Cell have access to all methods of the Cell that don’t start with _
.
Methods that only have the self argument are automatically turned into cached properties and can
be used without ()
.
a(href=index_url)= _('back_to_index')
This uses the return value of a cell method def index_url(self): ...
as link target and the
translation for ‘back_to_index’ as link text.
Warning
Don’t put a space before the =
!
Often it’s nicer to put the code in the next line which has the same effect as the last example:
a(href=index_url)
= _('back_to_index')
Unescaped HTML
To output HTML without escaping, wrap the string in Python code with Markup()
from markupsafe
.
Unbuffered
-
can be used to run Jinja code directly, without output. Pug calls this unbuffered code.
This works like {% %}
in Jinja.
We use it for layout extension and blocks on the Jinja level but this may go away in the future.
- extends "ekklesia/layout.j2.jade"
- block content
.content
In Jinja syntax, that block looks like this:
{% block content %}
<div class="content"></div>
{% end block %}
Try to avoid putting code in templates, most of the time there are better ways to express things. Logic should be implemented in a Cell method or code called by a cell method.
Conditionals
Conditionals can check values for “truthiness” like in Jinja/Python:
if output
= output
Writes output
only if output is truthy (not empty string or not None, for example).
If … else is also supported:
if options.show_full_output
= full_output
else
= short_output
Plain Text
Text after a tag is just rendered as plain text:
p Some Text
You won’t need that often because we want to translate most of the strings.
Use a pipe to put plain text on a separate line. Whitespace after the pipe is included in the output.
p
|Some Text
| More Text
Whitespace at the end of the line is also rendered! This should be avoided because many editors will strip trailing whitespace and change semantics of the template.
<p>Some Text More Text</p>
Mixing Code with Text
Let’s say we want to output two values separated by a space:
p
= first_part
|
= second_part
Iteration
Use for to iterate over a sequence:
ul
for item in items
= li.list-item= item.text
Code Style
Always use 2 spaces for indentation. Do not mix!
Line length should not exceed 120, but sometimes it’s necessary to write longer lines.
Avoid putting
= output
directly after a HTML tag, especially when it has multiple attributes. Put it on a indented line instead.
Comments