--- /dev/null
+===================================
+Filters, Tests and Helper Functions
+===================================
+
+This part of the documentation lists the filter-, test- and helper functions
+you can use in templates.
+
+
+Filters
+=======
+
+In the examples above you might have noticed the pipe symbols. Pipe symbols tell
+the engine that it has to apply a filter on the variable. Here is a small example:
+
+.. sourcecode:: jinja
+
+ {{ variable|replace('foo', 'bar')|escape }}
+
+If you want, you can also put whitespace between the filters.
+
+This will look for a variable `variable`, pass it to the filter `replace`
+with the arguments ``'foo'`` and ``'bar'``, and pass the result to the filter
+`escape` that automatically XML-escapes the value. The `e` filter is an alias for
+`escape`. Here is the complete list of supported filters:
+
+[[list_of_filters]]
+
+.. admonition:: note
+
+ The filter operator has a pretty low priority. If you want to add fitered
+ values you have to put them into parentheses. The same applies if you want
+ to access attributes or return values:
+
+ .. sourcecode:: jinja
+
+ correct:
+ {{ (foo|filter) + (bar|filter) }}
+ wrong:
+ {{ foo|filter + bar|filter }}
+
+ correct:
+ {{ (foo|filter).attribute }}
+ wrong:
+ {{ foo|filter.attribute }}
+
+*new in Jinja 1.1*:
+
+Because the application can provide additional filters you can get a documentation
+of all the provided filters by calling ``debug.filters()``:
+
+.. sourcecode:: jinja
+
+ {{ debug.filters() }}
+ -> returns a plain text representation of all the filters
+
+ {{ debug.filters(False) }}
+ -> same as above but without the builtin ones.
+
+Tests
+=====
+
+You can use the `is` operator to perform tests on a value:
+
+.. sourcecode:: jinja
+
+ {{ 42 is numeric }} -> true
+ {{ "foobar" is numeric }} -> false
+ {{ 'FOO' is upper }} -> true
+
+These tests are especially useful when used in `if` conditions.
+
+[[list_of_tests]]
+
+*new in Jinja 1.1*:
+
+Because the application can provide additional tests you can get a documentation
+of all the provided tests by calling ``debug.tests()``:
+
+.. sourcecode:: jinja
+
+ {{ debug.tests() }}
+ -> returns a plain text representation of all the tests
+
+ {{ debug.tests(False) }}
+ -> same as above but without the builtin ones.
+
+
+Global Functions
+================
+
+Test functions and filter functions live in their own namespace. Global
+functions not. They behave like normal objects in the context. Beside the
+functions added by the application or framewhere there are two functions
+available per default:
+
+`range`
+
+ Works like the python `range function`_ just that it doesn't support
+ ranges greater than ``1000000``.
+
+`debug`
+
+ Function that outputs the contents of the context.
+
+`lipsum`
+
+ Generate some paragraphs of random text:
+
+ .. sourcecode:: jinja
+
+ {{ lipsum(5) }}
+ five html paragraphs
+
+ {{ lipsum(2, False) }}
+ two ascii only paragraphs
+
+ Per default a paragraph is between 20 and 100 words long. You can
+ override this default with the third and fourth parameter:
+
+ .. sourcecode:: jinja
+
+ {{ lipsum(10, True, 50, 200) }}
+ generate 10 HTML paragraphs between 50 and 200 words.
+
+ *new in Jinja 1.1*
+
+`watchchanges`
+
+ Jinja does not provide an django like ``{% ifchanged %}`` tag. As
+ replacement for this tag there is a special function in the namespace
+ called `watchchanges`.
+
+ You can use it like this:
+
+ .. sourcecode:: html+jinja
+
+ {% for changed, article in watchchanges(articles, 'date', 'day') %}
+ {% if changed %}<h3>{{ articles.date.day }}</h3>{% endif %}
+ <h4>{{ article.title|e }}</h4>
+ <p>{{ article.body|e }}</p>
+ {% endif %}
+
+ For each iteration `watchchanges` will check the given attribute. If it
+ changed to the former iteration the first yielded item (in this example
+ it's called `changed`) will be `true`, else `false`.
+
+ In this example `articles` is a list of articles for the template with
+ an attribute called `date.day` which represents the current day. To only
+ add a new day headline if the day has changed `watchchanges` is now told
+ to check `articles.date.days`.
+
+ If you want to observe more than one attribute you can provide pairs:
+
+ .. sourcecode:: html+jinja
+
+ {% for changed, item in watchchanges(foo, ('a', 'b'), ('a', 'c')) %}
+ ...
+ {% endfor %}
+
+ Note that if you want to watch two first level attributes you have to
+ either use the list syntax `[]` or add a colon:
+
+ .. sourcecode:: html+jinja
+
+ {% for changed, item in watchchanges(foo, ['a'], ('b',)) %}
+ ...
+ {% endfor %}
+
+ otherwise Jinja cannot differ between a pair of parentheses to group
+ expressions or the sequence syntax.
+
+ If you don't provide any arguments the value of the variable itself
+ is checked.
+
+ *new in Jinja 1.1*
+
+
+Global Constants
+================
+
+Jinja provides some special variables which cannot be overridden in templates.
+Those are not affected by the variable lookup:
+
+ `_`, `true`, `false`, `none`, `undefined`
+
+You cannot use those names for your own variables or macros. It's however no
+problem to have blocks with that name.
+
+**Notice** due to a bug in Jinja 1.0 it was possible to override `_`, `true`,
+`false`, `none` and `undefined` from the template by either using `{% set %}`
+or in a for loop. While overriding `true`, `false` etc just caused nothing
+overriding the translation marker `_` would crash the translation interface.
+If you want to use `_` for unpacking in for loops (eg. skipping items) you
+have to give it a proper name:
+
+.. sourcecode:: jinja
+
+ {% for key, ignore in mydict|dictsort %}
+ {{ key|e }}
+ {% endfor %}
+
+
+.. _range function: http://docs.python.org/tut/node6.html#SECTION006300000000000000000
If you have numerical indices you have to use the [] syntax:
{{ users[0].username }}
-Filters
-=======
-
-In the examples above you might have noticed the pipe symbols. Pipe symbols tell
-the engine that it has to apply a filter on the variable. Here is a small example:
-
-.. sourcecode:: jinja
-
- {{ variable|replace('foo', 'bar')|escape }}
-
-If you want, you can also put whitespace between the filters.
-
-This will look for a variable `variable`, pass it to the filter `replace`
-with the arguments ``'foo'`` and ``'bar'``, and pass the result to the filter
-`escape` that automatically XML-escapes the value. The `e` filter is an alias for
-`escape`. Here is the complete list of supported filters:
-
-[[list_of_filters]]
-
-.. admonition:: note
-
- The filter operator has a pretty low priority. If you want to add fitered
- values you have to put them into parentheses. The same applies if you want
- to access attributes or return values:
-
- .. sourcecode:: jinja
-
- correct:
- {{ (foo|filter) + (bar|filter) }}
- wrong:
- {{ foo|filter + bar|filter }}
-
- correct:
- {{ (foo|filter).attribute }}
- wrong:
- {{ foo|filter.attribute }}
-
-*new in Jinja 1.1*:
-
-Because the application can provide additional filters you can get a documentation
-of all the provided filters by calling ``debug.filters()``:
-
-.. sourcecode:: jinja
-
- {{ debug.filters() }}
- -> returns a plain text representation of all the filters
-
- {{ debug.filters(False) }}
- -> same as above but without the builtin ones.
-
-Tests
-=====
-
-You can use the `is` operator to perform tests on a value:
-
-.. sourcecode:: jinja
-
- {{ 42 is numeric }} -> true
- {{ "foobar" is numeric }} -> false
- {{ 'FOO' is upper }} -> true
-
-These tests are especially useful when used in `if` conditions.
-
-[[list_of_tests]]
-
-*new in Jinja 1.1*:
-
-Because the application can provide additional tests you can get a documentation
-of all the provided tests by calling ``debug.tests()``:
-
-.. sourcecode:: jinja
-
- {{ debug.tests() }}
- -> returns a plain text representation of all the tests
-
- {{ debug.tests(False) }}
- -> same as above but without the builtin ones.
-
-
-Global Functions
-================
-
-Test functions and filter functions live in their own namespace. Global
-functions not. They behave like normal objects in the context. Beside the
-functions added by the application or framewhere there are two functions
-available per default:
-
-`range`
-
- Works like the python `range function`_ just that it doesn't support
- ranges greater than ``1000000``.
-
-`debug`
-
- Function that outputs the contents of the context.
-
-`lipsum`
-
- Generate some paragraphs of random text:
-
- .. sourcecode:: jinja
-
- {{ lipsum(5) }}
- five html paragraphs
-
- {{ lipsum(2, False) }}
- two ascii only paragraphs
-
- Per default a paragraph is between 20 and 100 words long. You can
- override this default with the third and fourth parameter:
-
- .. sourcecode:: jinja
-
- {{ lipsum(10, True, 50, 200) }}
- generate 10 HTML paragraphs between 50 and 200 words.
-
- *new in Jinja 1.1*
-
-`watchchanges`
-
- Jinja does not provide an django like ``{% ifchanged %}`` tag. As
- replacement for this tag there is a special function in the namespace
- called `watchchanges`.
-
- You can use it like this:
-
- .. sourcecode:: html+jinja
-
- {% for changed, article in watchchanges(articles, 'date', 'day') %}
- {% if changed %}<h3>{{ articles.date.day }}</h3>{% endif %}
- <h4>{{ article.title|e }}</h4>
- <p>{{ article.body|e }}</p>
- {% endif %}
-
- For each iteration `watchchanges` will check the given attribute. If it
- changed to the former iteration the first yielded item (in this example
- it's called `changed`) will be `true`, else `false`.
-
- In this example `articles` is a list of articles for the template with
- an attribute called `date.day` which represents the current day. To only
- add a new day headline if the day has changed `watchchanges` is now told
- to check `articles.date.days`.
-
- If you want to observe more than one attribute you can provide pairs:
-
- .. sourcecode:: html+jinja
-
- {% for changed, item in watchchanges(foo, ('a', 'b'), ('a', 'c')) %}
- ...
- {% endfor %}
-
- Note that if you want to watch two first level attributes you have to
- either use the list syntax `[]` or add a colon:
-
- .. sourcecode:: html+jinja
-
- {% for changed, item in watchchanges(foo, ['a'], ('b',)) %}
- ...
- {% endfor %}
-
- otherwise Jinja cannot differ between a pair of parentheses to group
- expressions or the sequence syntax.
-
- If you don't provide any arguments the value of the variable itself
- is checked.
-
- *new in Jinja 1.1*
-
Loops
=====
{% endfor %}
</ul>
-*Important* Contrary to Python is the optional ``else`` block only
+*Important* Contrary to Python is the optional `else` block only
executed if there was no iteration because the sequence was empty.
Inside of a `for` loop block you can access some special variables:
If a macro parameter is called `varargs` the additional extra
arguments are not accessible.
-
-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.
-
-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 straighforward. If a template contains a
-``{% 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 top level
-or inside of 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 executation.
-
-**possible**:
-
- .. sourcecode:: jinja
-
- {% extends 'master.html' %}
- {% block body %}
- {% if some_condition %}
- {% block myblock %}
- ...
- {% endblock %}
- {% endblock %}
- {% 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.
-
-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
-
+For information regarding the visibility of macros have a look at the
+`Scopes and Variable Behavior`_ section.
Template Inclusion
==================
If you define a macro called ``my_helper`` in ``myhelpers.html``, you can now
use it from the template as shown above.
+Because of the
+
Filtering Blocks
================
This should ouput ``foobar``.
-Scopes
-======
-
-Jinja has multiple scopes. A scope is something like a new transparent foil on
-a stack of foils. You can only write to the outermost foil but read all of them
-since you can look through them. If you remove the top foil all data on that
-foil disappears. Some tags in Jinja add a new layer to the stack. Currently
-these are `block`, `for`, `macro` and `filter`. This means that variables and
-other elements defined inside a macro, loop or some of the other tags listed
-above will be only available in that block. Here an example:
-
-.. sourcecode:: jinja
-
- {% macro angryhello name %}
- {% set angryname = name|upper %}
- Hello {{ name }}. Hello {{ name }}!
- HELLO {{ angryname }}!!!!!!111
- {% endmacro %}
-
-The variable ``angryname`` just exists inside the macro, not outside it.
-
-Defined macros appear on the context as variables. Because of this, they are
-affected by the scoping too. A macro defined inside of a macro is just available
-in those two macros (the macro itself and the macro it's defined in).
-
-Template Globals
-================
-
-A special threatment exists for template code outside of visible blocks in
-child templates. This code will be executed **before** the layout template
-code. Thus it can be used to propagate values back to the layout template or
-import macros from templates for rendering.
-
-Such code can output data but it won't appear in the final rendering. So no
-additional whitespace will pollute the template.
-
-Because this code is executed before the actual layout template code it's
-possible that the layout code overrides some of those variables. Usually
-this is not a problem because of different variable names but it can be
-a problem if you plan to specify default values.
-
-In that case you have to test if the variable is not defined before setting
-it:
-
-.. sourcecode:: jinja
-
- {% if not page_title %}
- {% set page_title = 'Default Page Title' %}
- {% endif %}
-
-You can of course also use the `|default` filter.
-
-.. admonition:: Explanation
-
- This template stored as `a.html`:
-
- .. sourcecode:: html+jinja
-
- <title>{{ title|default('Untitled') }}</title>
- <body>{% block body %}{% endblock %}
-
- ...and this child template stored as `b.html`:
-
- .. sourcecode:: html+jinja
-
- {% extends 'a.html' %}
- {% include 'macros.tmpl' %}
- {% set title = 'My Page' %}
- {% block body %}{{ wrap(42) }}{% endblock %}
-
- ...and this code in `macros.tmpl`:
-
- .. sourcecode:: html+jinja
-
- {% macro wrap(text) %}
- [{{ text }}]
- {% endmacro %}
-
- ..will translate to something with the same semantics as this (just
- that the value is not stored in a variable):
-
- .. sourcecode:: html+jinja
-
- {% filter capture('captured', true) %}
- {% macro wrap(text) %}
- [{{ text }}]
- {% endmacro %}
- {% set title='My Page' %}
- {% endfilter %}
- <title>{{ title|default('Untitled') }}</title>
- <body>
- {{ wrap(42) }}
- </body>
-
-.. admonition:: Note
-
- This implementation was improved in Jinja 1.1. In Jinja 1.0 blocks that
- were not top-level were not propagated to the layout template. This made
- it impossible to use conditional expressions for inclusion in non root
- templates.
-
-
-Undefined Variables
-===================
-
-If you have already worked with python you probably know about the fact that
-undefined variables raise an exception. This is different in Jinja. There is a
-special value called `undefined` that represents values that do not exist.
-
-Depending on the configuration it will behave different.
-
-In order to check if a value is defined you can use the `defined` test:
-
-.. sourcecode:: jinja
-
- {{ myvariable is not defined }}
- will return true if the variable does not exist.
-
-`SilentUndefined`:
-
- The silent `undefined` is the default behavior. The `undefined` object works
- complete different from any variables you maybe know. If you print it
- using ``{{ variable }}`` it will not appear because it's literally empty.
- If you try to iterate over it, it will work. But no items are returned.
-
- In order to check if a value is defined you can use the `defined` test:
-
- There are also some additional rules regarding this special value. Any
- mathematical operators (``+``, ``-``, ``*``, ``/``) return the operand
- as result:
-
- .. sourcecode:: jinja
-
- {{ undefined + "foo" }}
- returns "foo"
-
- {{ undefined - 42 }}
- returns 42. Note: not -42!
-
- In any expression `undefined` evaluates to `false`. It has no length, all
- attribute calls return undefined, calling too:
-
- .. sourcecode:: jinja
-
- {{ undefined.attribute().attribute_too[42] }}
- still returns `undefined`.
-
-`ComplainingUndefined`:
-
- Starting with Jinja 1.1 it's possible to replace the default undefined
- object with different values. The other common undefined object which
- comes with Jinja is the `ComplainingUndefined` object.
-
- It raises exceptions as soon as you either render it or want to iterate
- over it or try to access attributes etc.
-
-
-Escaping
-========
-
-Sometimes you might want to add Jinja syntax elements into the template
-without executing them. In that case you have quite a few possibilities.
-
-For small parts this might be a good way:
-
-.. sourcecode:: jinja
-
- {{ "{{ foo }} is variable syntax and {% foo %} is block syntax" }}
-
-When you have multiple elements you can use the ``raw`` block:
-
-.. sourcecode:: jinja
-
- {% raw %}
- Filtering blocks works like this in Jinja:
- {% filter escape %}
- <html>
- <code>goes here</code>
- </html>
- {% endfilter %}
- {% endraw %}
+For information regarding the visibility of variables have a look at the
+`Scopes and Variable Behavior`_ section.
Reserved Keywords
=================
on the application side. But it's very unlikely that new keywords will be
added.
-Global Constants
-================
-
-Jinja provides some special variables which cannot be overridden in templates.
-Those are not affected by the variable lookup:
-
- `_`, `true`, `false`, `none`, `undefined`
-
-You cannot use those names for your own variables or macros. It's however no
-problem to have blocks with that name.
-
-**Notice** due to a bug in Jinja 1.0 it was possible to override `_`, `true`,
-`false`, `none` and `undefined` from the template by either using `{% set %}`
-or in a for loop. While overriding `true`, `false` etc just caused nothing
-overriding the translation marker `_` would crash the translation interface.
-If you want to use `_` for unpacking in for loops (eg. skipping items) you
-have to give it a proper name:
-
-.. sourcecode:: jinja
-
- {% for key, ignore in mydict|dictsort %}
- {{ key|e }}
- {% endfor %}
-
-Whitespace
-==========
-
-If the Jinja environment was created with ``trim_blocks`` set to true the
-first newline after a template tag is removed automatically (php like
-processing).
-
-Starting with `Jinja 1.1` you can also handle some whitespace rules in the
-template. If you put an minus sign (`-`) to the start or end of an block
-(for example a `for` tag) or a comment, variable element you can remove
-the whitespaces after that block or before that block:
-
-.. sourcecode:: jinja
-
- {% for item in seq -%}
- {{ item }}
- {%- endfor %}
-
-This will yield all elements without whitespace between them because they
-are automatically removed. This of course works for other tags too:
-
-.. sourcecode:: jinja
-
- {% for user in userlist -%}
- {{ user|e -}}
- {% if not loop.last %},{% endif %}
- {%- endfor %}
-
-Note that you must not use a whitespace between the tag and the minus sign:
-
-.. sourcecode:: jinja
-
- valid:
- {%- if foo -%}...{% endif %}
-
- invalid:
-
- {% - if foo - %}...{% endif %}
-
-Internationalization
-====================
-
-If the application is configured for i18n, you can define translatable blocks
-for translators using the `trans` tag or the special underscore function:
-
-.. sourcecode:: jinja
-
- {% trans %}
- this is a translatable block
- {% endtrans %}
-
- {% trans "This is a translatable string" %}
-
- {{ _("This is a translatable string") }}
-
-The latter one is useful if you want translatable arguments for filters etc.
-
-If you want to have plural forms too, use the `pluralize` block:
-
-.. sourcecode:: jinja
-
- {% trans users=users %}
- One user found.
- {% pluralize %}
- {{ users }} users found.
- {% endtrans %}
-
- {% trans first=(users|first).username|escape, user=users|length %}
- one user {{ first }} found.
- {% pluralize users %}
- {{ users }} users found, the first one is called {{ first }}.
- {% endtrans %}
-
-If you have multiple arguments, the first one is assumed to be the indicator (the
-number that is used to determine the correct singular or plural form. If you
-don't have the indicator variable on position 1 you have to tell the `pluralize`
-tag the correct variable name.
-
-Inside translatable blocks you cannot use blocks or expressions (however you can
-still use the ``raw`` block which will work as expected). The variable
-print syntax (``{{ variablename }}``) is the only way to insert the variables
-defined in the ``trans`` header. Filters must be applied in the header.
-
-.. admonition:: note
-
- Please make sure that you always use pluralize blocks where required.
- Many languages have more complex plural forms than the English language.
-
- Never try to workaround that issue by using something like this:
-
- .. sourcecode:: jinja
-
- {% if count != 1 %}
- {{ count }} users found.
- {% else %}
- one user found.
- {% endif %}
-
-*New in Jinja 1.1*: It's now possible to use the marker name as implicit
-default:
-
-.. sourcecode:: jinja
-
- instead of this version:
-
- {% trans username=username %}Hello {{ username }}!{% endtrans %}
-
- you can now write this:
-
- {% trans username %}Hello {{ username }}!{% endtrans %}
-
Bleeding Edge
=============
</ul>
.. _slicing chapter: http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
-.. _range function: http://docs.python.org/tut/node6.html#SECTION006300000000000000000
+.. _Scopes and Variable Behavior: scopes.txt
--- /dev/null
+=======================
+Whitespace and Escaping
+=======================
+
+This section of the documentation explains how to remove unused whitespace
+from the templates and embed raw Jinja syntax.
+
+Escaping
+========
+
+Sometimes you might want to add Jinja syntax elements into the template
+without executing them. In that case you have quite a few possibilities.
+
+For small parts this might be a good way:
+
+.. sourcecode:: jinja
+
+ {{ "{{ foo }} is variable syntax and {% foo %} is block syntax" }}
+
+When you have multiple elements you can use the ``raw`` block:
+
+.. sourcecode:: jinja
+
+ {% raw %}
+ Filtering blocks works like this in Jinja:
+ {% filter escape %}
+ <html>
+ <code>goes here</code>
+ </html>
+ {% endfilter %}
+ {% endraw %}
+
+
+Whitespace
+==========
+
+If the Jinja environment was created with ``trim_blocks`` set to true the
+first newline after a template tag is removed automatically (php like
+processing).
+
+Starting with `Jinja 1.1` you can also handle some whitespace rules in the
+template. If you put an minus sign (`-`) to the start or end of an block
+(for example a `for` tag) or a comment, variable element you can remove
+the whitespaces after that block or before that block:
+
+.. sourcecode:: jinja
+
+ {% for item in seq -%}
+ {{ item }}
+ {%- endfor %}
+
+This will yield all elements without whitespace between them because they
+are automatically removed. This of course works for other tags too:
+
+.. sourcecode:: jinja
+
+ {% for user in userlist -%}
+ {{ user|e -}}
+ {% if not loop.last %},{% endif %}
+ {%- endfor %}
+
+Note that you must not use a whitespace between the tag and the minus sign:
+
+.. sourcecode:: jinja
+
+ valid:
+ {%- if foo -%}...{% endif %}
+
+ invalid:
+
+ {% - if foo - %}...{% endif %}
- **Template Designer Documentation**:
- - `Syntax Reference <designerdoc.txt>`_ - the designer documentation. Put
- this under your pillow.
+ - `Syntax Reference <designerdoc.txt>`_ - quick overview over the Jinja
+ syntax elements.
+
+ - `Template Inheritance <inheritance.txt>`_ - template inheritance howto.
+
+ - `Filters, Tests and Helper Functions <builtins.txt>`_ - list of filters
+ and test/helper functions.
+
+ - `Whitespace and Escaping <escaping.txt>`_ - how to escape markup and
+ control whitespace.
+
+ - `Scopes and Variable Behavior <scopes.txt>`_ - behavior of undefined
+ variables and scoping rules.
+
+ - `Template Internationalization <templatei18n.txt>`_ - how to internationalize
+ Jinja templates.
- `Differences To Django <fromdjango.txt>`_ - coming from django? Then this
document is for you.
--- /dev/null
+====================
+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.
+
+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 straighforward. If a template contains a
+``{% 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 top level
+or inside of 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 executation.
+
+**possible**:
+
+ .. sourcecode:: jinja
+
+ {% extends 'master.html' %}
+ {% block body %}
+ {% if some_condition %}
+ {% block myblock %}
+ ...
+ {% endblock %}
+ {% endblock %}
+ {% 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.
+
+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
# just give access to a and b. Default is all
# note that this also disallows the functions from below.
- # if you use jinja_allowed_attributes you don't have to
- # do the code below because methods are threaded as attributes
- # too.
+ # if you use jinja_allowed_attributes you don't have add the
+ # code below since methods are treated as attributes too.
jinja_allowed_attributes = ['a', 'b']
def __init__(self, ...):
--- /dev/null
+============================
+Scopes and Variable Behavior
+============================
+
+This section of the documentation covers the Jinja behavior regarding
+variable visibility.
+
+Scopes
+======
+
+Jinja has multiple scopes. A scope is something like a new transparent foil on
+a stack of foils. You can only write to the outermost foil but read all of them
+since you can look through them. If you remove the top foil all data on that
+foil disappears. Some tags in Jinja add a new layer to the stack. Currently
+these are `block`, `for`, `macro` and `filter`. This means that variables and
+other elements defined inside a macro, loop or some of the other tags listed
+above will be only available in that block. Here an example:
+
+.. sourcecode:: jinja
+
+ {% macro angryhello name %}
+ {% set angryname = name|upper %}
+ Hello {{ name }}. Hello {{ name }}!
+ HELLO {{ angryname }}!!!!!!111
+ {% endmacro %}
+
+The variable ``angryname`` just exists inside the macro, not outside it.
+
+Defined macros appear on the context as variables. Because of this, they are
+affected by the scoping too. A macro defined inside of a macro is just available
+in those two macros (the macro itself and the macro it's defined in).
+
+Template Globals
+================
+
+A special threatment exists for template code outside of visible blocks in
+child templates. This code will be executed **before** the layout template
+code. Thus it can be used to propagate values back to the layout template or
+import macros from templates for rendering.
+
+Such code can output data but it won't appear in the final rendering. So no
+additional whitespace will pollute the template.
+
+Because this code is executed before the actual layout template code it's
+possible that the layout code overrides some of those variables. Usually
+this is not a problem because of different variable names but it can be
+a problem if you plan to specify default values.
+
+In that case you have to test if the variable is not defined before setting
+it:
+
+.. sourcecode:: jinja
+
+ {% if not page_title %}
+ {% set page_title = 'Default Page Title' %}
+ {% endif %}
+
+You can of course also use the `|default` filter.
+
+.. admonition:: Explanation
+
+ This template stored as `a.html`:
+
+ .. sourcecode:: html+jinja
+
+ <title>{{ title|default('Untitled') }}</title>
+ <body>{% block body %}{% endblock %}
+
+ ...and this child template stored as `b.html`:
+
+ .. sourcecode:: html+jinja
+
+ {% extends 'a.html' %}
+ {% include 'macros.tmpl' %}
+ {% set title = 'My Page' %}
+ {% block body %}{{ wrap(42) }}{% endblock %}
+
+ ...and this code in `macros.tmpl`:
+
+ .. sourcecode:: html+jinja
+
+ {% macro wrap(text) %}
+ [{{ text }}]
+ {% endmacro %}
+
+ ..will translate to something with the same semantics as this (just
+ that the value is not stored in a variable):
+
+ .. sourcecode:: html+jinja
+
+ {% filter capture('captured', true) %}
+ {% macro wrap(text) %}
+ [{{ text }}]
+ {% endmacro %}
+ {% set title='My Page' %}
+ {% endfilter %}
+ <title>{{ title|default('Untitled') }}</title>
+ <body>
+ {{ wrap(42) }}
+ </body>
+
+.. admonition:: Note
+
+ This implementation was improved in Jinja 1.1. In Jinja 1.0 blocks that
+ were not top-level were not propagated to the layout template. This made
+ it impossible to use conditional expressions for inclusion in non root
+ templates.
+
+Undefined Variables
+===================
+
+If you have already worked with python you probably know about the fact that
+undefined variables raise an exception. This is different in Jinja. There is a
+special value called `undefined` that represents values that do not exist.
+
+Depending on the configuration it will behave different.
+
+In order to check if a value is defined you can use the `defined` test:
+
+.. sourcecode:: jinja
+
+ {{ myvariable is not defined }}
+ will return true if the variable does not exist.
+
+`SilentUndefined`:
+
+ The silent `undefined` is the default behavior. The `undefined` object works
+ complete different from any variables you maybe know. If you print it
+ using ``{{ variable }}`` it will not appear because it's literally empty.
+ If you try to iterate over it, it will work. But no items are returned.
+
+ In order to check if a value is defined you can use the `defined` test:
+
+ There are also some additional rules regarding this special value. Any
+ mathematical operators (``+``, ``-``, ``*``, ``/``) return the operand
+ as result:
+
+ .. sourcecode:: jinja
+
+ {{ undefined + "foo" }}
+ returns "foo"
+
+ {{ undefined - 42 }}
+ returns 42. Note: not -42!
+
+ In any expression `undefined` evaluates to `false`. It has no length, all
+ attribute calls return undefined, calling too:
+
+ .. sourcecode:: jinja
+
+ {{ undefined.attribute().attribute_too[42] }}
+ still returns `undefined`.
+
+`ComplainingUndefined`:
+
+ Starting with Jinja 1.1 it's possible to replace the default undefined
+ object with different values. The other common undefined object which
+ comes with Jinja is the `ComplainingUndefined` object.
+
+ It raises exceptions as soon as you either render it or want to iterate
+ over it or try to access attributes etc.
--- /dev/null
+=============================
+Template Internationalization
+=============================
+
+If the application is configured for i18n, you can define translatable blocks
+for translators using the `trans` tag or the special underscore function:
+
+.. sourcecode:: jinja
+
+ {% trans %}
+ this is a translatable block
+ {% endtrans %}
+
+ {% trans "This is a translatable string" %}
+
+ {{ _("This is a translatable string") }}
+
+The latter one is useful if you want translatable arguments for filters etc.
+
+If you want to have plural forms too, use the `pluralize` block:
+
+.. sourcecode:: jinja
+
+ {% trans users=users %}
+ One user found.
+ {% pluralize %}
+ {{ users }} users found.
+ {% endtrans %}
+
+ {% trans first=(users|first).username|escape, user=users|length %}
+ one user {{ first }} found.
+ {% pluralize users %}
+ {{ users }} users found, the first one is called {{ first }}.
+ {% endtrans %}
+
+If you have multiple arguments, the first one is assumed to be the indicator (the
+number that is used to determine the correct singular or plural form. If you
+don't have the indicator variable on position 1 you have to tell the `pluralize`
+tag the correct variable name.
+
+Inside translatable blocks you cannot use blocks or expressions (however you can
+still use the ``raw`` block which will work as expected). The variable
+print syntax (``{{ variablename }}``) is the only way to insert the variables
+defined in the ``trans`` header. Filters must be applied in the header.
+
+.. admonition:: note
+
+ Please make sure that you always use pluralize blocks where required.
+ Many languages have more complex plural forms than the English language.
+
+ Never try to workaround that issue by using something like this:
+
+ .. sourcecode:: jinja
+
+ {% if count != 1 %}
+ {{ count }} users found.
+ {% else %}
+ one user found.
+ {% endif %}
+
+*New in Jinja 1.1*: It's now possible to use the marker name as implicit
+default:
+
+.. sourcecode:: jinja
+
+ instead of this version:
+
+ {% trans username=username %}Hello {{ username }}!{% endtrans %}
+
+ you can now write this:
+
+ {% trans username %}Hello {{ username }}!{% endtrans %}