Table of Contents
Syntax
Variables
{{ foo.bar }}
{{ foo['bar'] }}
- Both work the same whether 'foo' is a dict or an object.
Filters
{{ name|striptags|title }}
== {{ title(striptags(name)) }}
{{ listx|join(', ') }}
== {{ str.join(', ', listx) }}
Tests
{% if variable is defined %}
value of variable: {{ variable }}
{% else %}
variable is not defined
{% endif %}
{# note: commented-out template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}
Whitespace Control
# default
{% if True %}
# strip
{%- if True %}
# don't strip
{% if True %+}
- a single trailing newline is stripped if present
- other whitespace (spaces, tabs, newlines etc.) is returned unchanged
+/-
can be placed right after {%
and/or right before %}
of a block
Escaping
{{ '{{' }}
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}
Line Statements
# for item in seq:
<li>{{ item }}</li> ## this comment is ignored
# endfor
Template Inheritance
base.html
-
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2008 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
</html>
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p>
{% endblock %}
{% block something %}
can be replaced by child templates
{{ super() }}
gives back the results of the parent block
Block Nesting and Scope
{% for item in seq %}
<li>{% block loop_item scoped %}{{ item }}{% endblock %}</li>
{% endfor %}
- In some cases,
scoped
keyword required
For
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no users found</em></li>
{% endfor %}
</ul>
- Jinja loops cannot break anyway,
{% else %}
with {% for %}
means 'no iteration occurred'
<ul class="sitemap">
{%- for item in sitemap recursive %}
<li><a href="{{ item.href|e }}">{{ item.title }}</a>
{%- if item.children -%}
<ul class="submenu">{{ loop(item.children) }}</ul>
{%- endif %}</li>
{%- endfor %}
</ul>
- Note
recursive
and loop()
Macros
{% macro input(name, value='', type='text', size=20) -%}
<input type="{{ type }}" name="{{ name }}" value="{{
value|e }}" size="{{ size }}">
{%- endmacro %}
<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>
{% macro render_dialog(title, class='dialog') -%}
<div class="{{ class }}">
<h2>{{ title }}</h2>
<div class="contents">
{{ caller() }}
</div>
</div>
{%- endmacro %}
{% call render_dialog('Hello World') %}
This is a simple dialog rendered by using a macro and
a call block.
{% endcall %}
{% macro dump_users(users) -%}
<ul>
{%- for user in users %}
<li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
{%- endfor %}
</ul>
{%- endmacro %}
{% call(user) dump_users(list_of_user) %}
<dl>
<dl>Realname</dl>
<dd>{{ user.realname|e }}</dd>
<dl>Description</dl>
<dd>{{ user.description }}</dd>
</dl>
{% endcall %}
Filters (section)
{% filter upper %}
This text becomes uppercase
{% endfilter %}
Assignments
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% set key, value = call_something() %}
{% set navigation %}
<li><a href="/">Index</a>
<li><a href="/downloads">Downloads</a>
{% endset %}
{% set reply | wordwrap %}
You wrote:
{{ message }}
{% endset %}
Include
{% include 'header.html' %}
Body
{% include 'footer.html' %}
{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}
% include ['page_detailed.html', 'page.html'] %}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}
Import
forms.html
-
{% macro input(name, value='', type='text') -%}
<input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{%- endmacro %}
{%- macro textarea(name, value='', rows=10, cols=40) -%}
<textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols
}}">{{ value|e }}</textarea>
{%- endmacro %}
{% import 'forms.html' as forms %}
<dl>
<dt>Username</dt>
<dd>{{ forms.input('username') }}</dd>
<dt>Password</dt>
<dd>{{ forms.input('password', type='password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>
{% from 'forms.html' import input as input_field, textarea %}
<dl>
<dt>Username</dt>
<dd>{{ input_field('username') }}</dd>
<dt>Password</dt>
<dd>{{ input_field('password', type='password') }}</dd>
</dl>
<p>{{ textarea('comment') }}</p>
- Macros and variables starting with one or more underscores are private and cannot be imported.
Topics
Environment
- Most apps will create one
Environment
- Configures things like
{%
, {{
, {#
- Consider
Environment
as a factory of templates
Sandbox
- Can be used to evaluate untrusted code.
- If the template tries to access insecure code a
SecurityError
is raised