diff options
| author | Georg Brandl <georg@python.org> | 2021-01-18 21:24:00 +0100 |
|---|---|---|
| committer | Georg Brandl <georg@python.org> | 2021-01-18 22:08:36 +0100 |
| commit | 2a3d3a7d5b9c60dedf6638d876161d9563faebcf (patch) | |
| tree | 809c0b4a686db98f5954afa1944404cd9652c6b2 /tests/lexers/rst/example2.txt | |
| parent | f0445be718da83541ea3401aad882f3937147263 (diff) | |
| download | pygments-git-examplefiles.tar.gz | |
Move test_examplefiles to new tests/lexers scheme.examplefiles
Diffstat (limited to 'tests/lexers/rst/example2.txt')
| -rw-r--r-- | tests/lexers/rst/example2.txt | 4628 |
1 files changed, 4628 insertions, 0 deletions
diff --git a/tests/lexers/rst/example2.txt b/tests/lexers/rst/example2.txt new file mode 100644 index 00000000..8194b8cd --- /dev/null +++ b/tests/lexers/rst/example2.txt @@ -0,0 +1,4628 @@ +---input--- +====================== +Designer Documentation +====================== + +This part of the Jinja documentaton is meant for template designers. + +Basics +====== + +The Jinja template language is designed to strike a balance between content +and application logic. Nevertheless you can use a python like statement +language. You don't have to know how Python works to create Jinja templates, +but if you know it you can use some additional statements you may know from +Python. + +Here is a small example template: + +.. 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" lang="en" xml:lang="en"> + <head> + <title>My Webpage</title> + </head> + <body> + <ul id="navigation"> + {% for item in navigation %} + <li><a href="{{ item.href|e }}">{{ item.caption|e }}</a></li> + {% endfor %} + </ul> + + <h1>My Webpage</h1> + {{ variable }} + </body> + </html> + +This covers the default settings. The application developer might have changed +the syntax from ``{% foo %}`` to ``<% foo %>`` or something similar. This +documentation just covers the default values. + +A variable looks like ``{{ foobar }}`` where foobar is the variable name. Inside +of statements (``{% some content here %}``) variables are just normal names +without the braces around it. In fact ``{{ foobar }}`` is just an alias for +the statement ``{% print foobar %}``. + +Variables are coming from the context provided by the application. Normally there +should be a documentation regarding the context contents but if you want to know +the content of the current context, you can add this to your template: + +.. sourcecode:: html+jinja + + <pre>{{ debug()|e }}</pre> + +A context isn't flat which means that each variable can has subvariables, as long +as it is representable as python data structure. You can access attributes of +a variable using the dot and bracket operators. The following examples show +this: + +.. sourcecode:: jinja + + {{ user.username }} + is the same as + {{ user['username'] }} + you can also use a variable to access an attribute: + {{ users[current_user].username }} + 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 + + Filters have 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: + + .. sourcecode:: jinja + + correct: + {{ (foo|filter) + (bar|filter) }} + wrong: + {{ foo|filter + bar|filter }} + + correct: + {{ (foo|filter).attribute }} + wrong: + {{ foo|filter.attribute }} + +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]] + +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. + +Loops +===== + +To iterate over a sequence, you can use the `for` loop. It basically looks like a +normal Python `for` loop and works pretty much the same: + +.. sourcecode:: html+jinja + + <h1>Members</h1> + <ul> + {% for user in users %} + <li>{{ loop.index }} / {{ loop.length }} - {{ user.username|escape }}</li> + {% else %} + <li><em>no users found</em></li> + {% endfor %} + </ul> + +*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: + ++----------------------+----------------------------------------+ +| Variable | Description | ++======================+========================================+ +| `loop.index` | The current iteration of the loop. | ++----------------------+----------------------------------------+ +| `loop.index0` | The current iteration of the loop, | +| | starting counting by 0. | ++----------------------+----------------------------------------+ +| `loop.revindex` | The number of iterations from the end | +| | of the loop. | ++----------------------+----------------------------------------+ +| `loop.revindex0` | The number of iterations from the end | +| | of the loop, starting counting by 0. | ++----------------------+----------------------------------------+ +| `loop.first` | True if first iteration. | ++----------------------+----------------------------------------+ +| `loop.last` | True if last iteration. | ++----------------------+----------------------------------------+ +| `loop.even` | True if current iteration is even. | ++----------------------+----------------------------------------+ +| `loop.odd` | True if current iteration is odd. | ++----------------------+----------------------------------------+ +| `loop.length` | Total number of items in the sequence. | ++----------------------+----------------------------------------+ +| `loop.parent` | The context of the parent loop. | ++----------------------+----------------------------------------+ + +Loops also support recursion. Let's assume you have a sitemap where each item +might have a number of child items. A template for that could look like this: + +.. sourcecode:: html+jinja + + <h1>Sitemap + <ul id="sitemap"> + {% for item in sitemap recursive %} + <li><a href="{{ item.url|e }}">{{ item.title|e }}</a> + {% if item.children %}<ul>{{ loop(item.children) }}</ul>{% endif %}</li> + {% endfor %} + </ul> + +What happens here? Basically the first thing that is different to a normal +loop is the additional ``recursive`` modifier in the `for`-loop declaration. +It tells the template engine that we want recursion. If recursion is enabled +the special `loop` variable is callable. If you call it with a sequence it will +automatically render the loop at that position with the new sequence as argument. + +Cycling +======= + +Sometimes you might want to have different text snippets for each row in a list, +for example to have alternating row colors. You can easily do this by using the +``{% cycle %}`` tag: + +.. sourcecode:: html+jinja + + <ul id="messages"> + {% for message in messages %} + <li class="{% cycle 'row1', 'row2' %}">{{ message|e }}</li> + {% endfor %} + </ul> + +Each time Jinja encounters a `cycle` tag it will cycle through the list +of given items and return the next one. If you pass it one item jinja assumes +that this item is a sequence from the context and uses this: + +.. sourcecode:: html+jinja + + <li style="color: {% cycle rowcolors %}">...</li> + +Conditions +========== + +Jinja supports Python-like `if` / `elif` / `else` constructs: + +.. sourcecode:: jinja + + {% if user.active %} + user {{ user.name|e }} is active. + {% elif user.deleted %} + user {{ user.name|e }} was deleted some time ago. + {% else %} + i don't know what's wrong with {{ user.username|e }} + {% endif %} + +If the user is active the first block is rendered. If not and the user was +deleted the second one, in all other cases the third one. + +You can also use comparison operators: + +.. sourcecode:: html+jinja + + {% if amount < 0 %} + <span style="color: red">{{ amount }}</span> + {% else %} + <span style="color: black">{{ amount }}</span> + {% endif %} + +.. admonition:: Note + + Of course you can use `or` / `and` and parentheses to create more complex + conditions, but usually the logic is already handled in the application and + you don't have to create such complex constructs in the template code. However + in some situations it might be a good thing to have the abilities to create + them. + +Operators +========= + +Inside ``{{ variable }}`` blocks, `if` conditions and many other parts you can +can use expressions. In expressions you can use any of the following operators: + + ======= =================================================================== + ``+`` add the right operand to the left one. + ``{{ 1 + 2 }}`` would return ``3``. + ``-`` subtract the right operand from the left one. + ``{{ 1 - 1 }}`` would return ``0``. + ``/`` divide the left operand by the right one. + ``{{ 1 / 2 }}`` would return ``0.5``. + ``*`` multiply the left operand with the right one. + ``{{ 2 * 2 }}`` would return ``4``. + ``**`` raise the left operand to the power of the right + operand. ``{{ 2**3 }}`` would return ``8``. + ``in`` perform sequence membership test. ``{{ 1 in [1,2,3] }}`` would + return true. + ``is`` perform a test on the value. See the section about + tests for more information. + ``|`` apply a filter on the value. See the section about + filters for more information. + ``and`` return true if the left and the right operand is true. + ``or`` return true if the left or the right operand is true. + ``not`` negate a statement (see below) + ``()`` call a callable: ``{{ user.get_username() }}``. Inside of the + parentheses you can use variables: ``{{ user.get(username) }}``. + ======= =================================================================== + +Note that there is no support for any bit operations or something similar. + +* special note regarding `not`: The `is` and `in` operators support negation + using an infix notation too: ``foo is not bar`` and ``foo not in bar`` + instead of ``not foo is bar`` and ``not foo in bar``. All other expressions + require a prefix notation: ``not (foo and bar)``. + +Boolean Values +============== + +In If-Conditions Jinja performs a boolean check. All empty values (eg: empty +lists ``[]``, empty dicts ``{}`` etc) evaluate to `false`. Numbers that are +equal to `0`/`0.00` are considered `false` too. The boolean value of other +objects depends on the behavior the application developer gave it. Usually +items are `true`. + +Here some examples that should explain it: + +.. sourcecode:: jinja + + {% if [] %} + will always be false because it's an empty list + + {% if {} %} + false too. + + {% if ['foo'] %} + this is true. Because the list is not empty. + + {% if "foobar" %} + this is also true because the string is not empty. + +Slicing +======= + +Some objects support slicing operations. For example lists: + +.. sourcecode:: jinja + + {% for item in items[:5] %} + This will only iterate over the first 5 items of the list + + {% for item in items[5:10] %} + This will only iterate from item 5 to 10. + + {% for item in items[:10:2] %} + This will only yield items from start to ten and only returing + even items. + +For more informations about slicing have a look at the `slicing chapter`_ +in the "Dive into Python" e-book. + +Macros +====== + +If you want to use a partial template in more than one place, you might want to +create a macro from it: + +.. sourcecode:: html+jinja + + {% macro show_user user %} + <h1>{{ user.name|e }}</h1> + <div class="test"> + {{ user.description }} + </div> + {% endmacro %} + +Now you can use it from everywhere in the code by passing it an item: + +.. sourcecode:: jinja + + {% for user in users %} + {{ show_user(user) }} + {% endfor %} + +You can also specify more than one value: + +.. sourcecode:: html+jinja + + {% macro show_dialog title, text %} + <div class="dialog"> + <h1>{{ title|e }}</h1> + <div class="test">{{ text|e }}</div> + </div> + {% endmacro %} + + {{ show_dialog('Warning', 'something went wrong i guess') }} + +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. + +Template Inclusion +================== + +You can load another template at a given position using ``{% include %}``. +Usually it's a better idea to use inheritance but if you for example want to +load macros, `include` works better than `extends`: + +.. sourcecode:: jinja + + {% include "myhelpers.html" %} + {{ my_helper("foo") }} + +If you define a macro called ``my_helper`` in ``myhelpers.html``, you can now +use it from the template as shown above. + +Filtering Blocks +================ + +Sometimes it could be a good idea to filter a complete block of text. For +example, if you want to escape some html code: + +.. sourcecode:: jinja + + {% filter escape %} + <html> + <code>goes here</code> + </html> + {% endfilter %} + +Of course you can chain filters too: + +.. sourcecode:: jinja + + {% filter lower|escape %} + <B>SOME TEXT</B> + {% endfilter %} + +returns ``"<b>some text</b>"``. + +Defining Variables +================== + +You can also define variables in the namespace using the ``{% set %}`` tag: + +.. sourcecode:: jinja + + {% set foo = 'foobar' %} + {{ foo }} + +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). For `set` +and `macro` two additional rules exist: If a macro is defined in an extended +template but outside of a visible block (thus outside of any block) will be +available in all blocks below. This allows you to use `include` statements to +load often used macros at once. + +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. + +This special variable 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. Comparing this value to any other value results in `false`. +Even if you compare it to itself: + +.. sourcecode:: jinja + + {{ undefined == undefined }} + will return false. Not even undefined is undefined :) + Use `is defined` / `is not defined`: + + {{ undefined is not defined }} + will return true. + +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`. + +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 %} + +Reserved Keywords +================= + +Jinja has some keywords you cannot use a variable names. This limitation +exists to make look coherent. Syntax highlighters won't mess things up and +you will don't have unexpected output. + +The following keywords exist and cannot be used as identifiers: + + `and`, `block`, `cycle`, `elif`, `else`, `endblock`, `endfilter`, + `endfor`, `endif`, `endmacro`, `endraw`, `endtrans`, `extends`, `filter`, + `for`, `if`, `in`, `include`, `is`, `macro`, `not`, `or`, `pluralize`, + `raw`, `recursive`, `set`, `trans` + +If you want to use such a name you have to prefix or suffix it or use +alternative names: + +.. sourcecode:: jinja + + {% for macro_ in macros %} + {{ macro_('foo') }} + {% endfor %} + +If future Jinja releases add new keywords those will be "light" keywords which +means that they won't raise an error for several releases but yield warnings +on the application side. But it's very unlikely that new keywords will be +added. + +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 %} + +.. _slicing chapter: http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice +.. _range function: http://docs.python.org/tut/node6.html#SECTION006300000000000000000 + +---tokens--- +'======================' Generic.Heading +'\n' Text + +'Designer Documentation' Generic.Heading +'\n' Text + +'======================' Generic.Heading +'\n' Text + +'\n' Text + +'This part of the Jinja documentaton is meant for template designers.' Text +'\n' Text + +'\n' Text + +'Basics' Generic.Heading +'\n' Text + +'======' Generic.Heading +'\n' Text + +'\n' Text + +'The Jinja template language is designed to strike a balance between content' Text +'\n' Text + +'and application logic. Nevertheless you can use a python like statement' Text +'\n' Text + +"language. You don't have to know how Python works to create Jinja templates," Text +'\n' Text + +'but if you know it you can use some additional statements you may know from' Text +'\n' Text + +'Python.' Text +'\n' Text + +'\n' Text + +'Here is a small example template' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n' Comment.Preproc + +' ' Text +' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'html' Name.Tag +' ' Text +'xmlns' Name.Attribute +'=' Operator +'"http://www.w3.org/1999/xhtml"' Literal.String +' ' Text +'lang' Name.Attribute +'=' Operator +'"en"' Literal.String +' ' Text +'xml:lang' Name.Attribute +'=' Operator +'"en"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'head' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'title' Name.Tag +'>' Punctuation +'My Webpage' Text +'<' Punctuation +'/' Punctuation +'title' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'head' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'body' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'ul' Name.Tag +' ' Text +'id' Name.Attribute +'=' Operator +'"navigation"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'item' Name.Variable +' ' Text +'in' Keyword +' ' Text +'navigation' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'li' Name.Tag +'>' Punctuation +'<' Punctuation +'a' Name.Tag +' ' Text +'href' Name.Attribute +'=' Operator +'"' Literal.String +'{{' Comment.Preproc +' ' Text +'item' Name.Variable +'.href' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'"' Literal.String +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'item' Name.Variable +'.caption' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'a' Name.Tag +'>' Punctuation +'<' Punctuation +'/' Punctuation +'li' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'endfor' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'ul' Name.Tag +'>' Punctuation +'\n\n' Text + +' ' Text +' ' Text +'<' Punctuation +'h1' Name.Tag +'>' Punctuation +'My Webpage' Text +'<' Punctuation +'/' Punctuation +'h1' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{{' Comment.Preproc +' ' Text +'variable' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'body' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'html' Name.Tag +'>' Punctuation +'\n\n' Text + +'This covers the default settings. The application developer might have changed' Text +'\n' Text + +'the syntax from ' Text +'``' Literal.String +'{% foo %}' Literal.String +'``' Literal.String +' to ' Text +'``' Literal.String +'<% foo %>' Literal.String +'``' Literal.String +' or something similar. This' Text +'\n' Text + +'documentation just covers the default values.' Text +'\n' Text + +'\n' Text + +'A variable looks like ' Text +'``' Literal.String +'{{ foobar }}' Literal.String +'``' Literal.String +' where foobar is the variable name. Inside' Text +'\n' Text + +'of statements (' Text +'``' Literal.String +'{% some content here %}' Literal.String +'``' Literal.String +') variables are just normal names' Text +'\n' Text + +'without the braces around it. In fact ' Text +'``' Literal.String +'{{ foobar }}' Literal.String +'``' Literal.String +' is just an alias for' Text +'\n' Text + +'the statement ' Text +'``' Literal.String +'{% print foobar %}' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +'\n' Text + +'Variables are coming from the context provided by the application. Normally there' Text +'\n' Text + +'should be a documentation regarding the context contents but if you want to know' Text +'\n' Text + +'the content of the current context, you can add this to your template' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<' Punctuation +'pre' Name.Tag +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'debug' Name.Variable +'(' Operator +')' Operator +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'pre' Name.Tag +'>' Punctuation +'\n\n' Text + +"A context isn't flat which means that each variable can has subvariables, as long" Text +'\n' Text + +'as it is representable as python data structure. You can access attributes of' Text +'\n' Text + +'a variable using the dot and bracket operators. The following examples show' Text +'\n' Text + +'this' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.username' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' is the same as\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'[' Operator +"'username'" Literal.String.Single +']' Operator +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' you can also use a variable to access an attribute:\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'users' Name.Variable +'[' Operator +'current_user' Name.Variable +']' Operator +'.username' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' If you have numerical indices you have to use the [] syntax:\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'users' Name.Variable +'[' Operator +'0' Literal.Number +']' Operator +'.username' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'Filters' Generic.Heading +'\n' Text + +'=======' Generic.Heading +'\n' Text + +'\n' Text + +'In the examples above you might have noticed the pipe symbols. Pipe symbols tell' Text +'\n' Text + +'the engine that it has to apply a filter on the variable. Here is a small example' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'variable' Name.Variable +'|' Operator +'replace' Name.Function +'(' Operator +"'foo'" Literal.String.Single +',' Operator +' ' Text +"'bar'" Literal.String.Single +')' Operator +'|' Operator +'escape' Name.Function +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'If you want, you can also put whitespace between the filters.' Text +'\n' Text + +'\n' Text + +'This will look for a variable ' Text +'`variable`' Name.Variable +', pass it to the filter ' Text +'`replace`' Name.Variable +'\n' Text + +'with the arguments ' Text +'``' Literal.String +"'foo'" Literal.String +'``' Literal.String +' and ' Text +'``' Literal.String +"'bar'" Literal.String +'``' Literal.String +', and pass the result to the filter' Text +'\n' Text + +'`escape`' Name.Variable +' that automatically XML-escapes the value. The ' Text +'`e`' Name.Variable +' filter is an alias for' Text +'\n' Text + +'`escape`' Name.Variable +'. Here is the complete list of supported filters' Text +':' Text +'\n' Text + +'\n' Text + +'[' Text +'[' Text +'list_of_filters]]' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'admonition' Operator.Word +'::' Punctuation +' ' Text +'note' Text +'\n' Text + +'\n' Text + +' Filters have a pretty low priority. If you want to add fitered values' Text +'\n' Text + +' you have to put them into parentheses. The same applies if you want to access' Text +'\n' Text + +' attributes' Text +':' Text +'\n' Text + +'\n' Text + +' ..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'correct:\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'(' Operator +'foo' Name.Variable +'|' Operator +'filter' Name.Function +')' Operator +' ' Text +'+' Operator +' ' Text +'(' Operator +'bar' Name.Variable +'|' Operator +'filter' Name.Function +')' Operator +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +'wrong:\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'foo' Name.Variable +'|' Operator +'filter' Name.Function +' ' Text +'+' Operator +' ' Text +'bar' Name.Variable +'|' Operator +'filter' Name.Function +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +' ' Text +'correct:\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'(' Operator +'foo' Name.Variable +'|' Operator +'filter' Name.Function +')' Operator +'.attribute' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +'wrong:\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'foo' Name.Variable +'|' Operator +'filter' Name.Function +'.attribute' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'Tests' Generic.Heading +'\n' Text + +'=====' Generic.Heading +'\n' Text + +'\n' Text + +'You can use the ' Text +'`is`' Name.Variable +' operator to perform tests on a value' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'4' Literal.Number +'2' Literal.Number +' ' Text +'is' Keyword +' ' Text +'numeric' Name.Function +' ' Text +'}}' Comment.Preproc +' -> true\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'"foobar"' Literal.String.Double +' ' Text +'is' Keyword +' ' Text +'numeric' Name.Function +' ' Text +'}}' Comment.Preproc +' -> false\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +"'FOO'" Literal.String.Single +' ' Text +'is' Keyword +' ' Text +'upper' Name.Function +' ' Text +'}}' Comment.Preproc +' -> true\n\n' Other + +'These tests are especially useful when used in ' Text +'`if`' Name.Variable +' conditions.' Text +'\n' Text + +'\n' Text + +'[' Text +'[' Text +'list_of_tests]]' Text +'\n' Text + +'\n' Text + +'Global Functions' Generic.Heading +'\n' Text + +'================' Generic.Heading +'\n' Text + +'\n' Text + +'Test functions and filter functions live in their own namespace. Global' Text +'\n' Text + +'functions not. They behave like normal objects in the context. Beside the' Text +'\n' Text + +'functions added by the application or framewhere there are two functions' Text +'\n' Text + +'available per default' Text +':' Text +'\n' Text + +'\n' Text + +'`range`' Name.Variable +'\n' Text + +' ' Text +'\n' Text + +' Works like the python ' Text +'`range function`_' Literal.String +" just that it doesn't support" Text +'\n' Text + +' ranges greater than ' Text +'``' Literal.String +'1000000' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +'\n' Text + +'`debug`' Name.Variable +'\n' Text + +'\n' Text + +' Function that outputs the contents of the context.' Text +'\n' Text + +'\n' Text + +'Loops' Generic.Heading +'\n' Text + +'=====' Generic.Heading +'\n' Text + +'\n' Text + +'To iterate over a sequence, you can use the ' Text +'`for`' Name.Variable +' loop. It basically looks like a' Text +'\n' Text + +'normal Python ' Text +'`for`' Name.Variable +' loop and works pretty much the same' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<' Punctuation +'h1' Name.Tag +'>' Punctuation +'Members' Text +'<' Punctuation +'/' Punctuation +'h1' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'ul' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'user' Name.Variable +' ' Text +'in' Keyword +' ' Text +'users' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'li' Name.Tag +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'loop' Name.Builtin +'.index' Name.Variable +' ' Text +'}}' Comment.Preproc +' / ' Text +'{{' Comment.Preproc +' ' Text +'loop' Name.Builtin +'.length' Name.Variable +' ' Text +'}}' Comment.Preproc +' - ' Text +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.username' Name.Variable +'|' Operator +'escape' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'li' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'else' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'li' Name.Tag +'>' Punctuation +'<' Punctuation +'em' Name.Tag +'>' Punctuation +'no users found' Text +'<' Punctuation +'/' Punctuation +'em' Name.Tag +'>' Punctuation +'<' Punctuation +'/' Punctuation +'li' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfor' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'ul' Name.Tag +'>' Punctuation +'\n\n' Text + +'*Important*' Generic.Emph +' Contrary to Python is the optional ' Text +'``' Literal.String +'else' Literal.String +'``' Literal.String +' block only' Text +'\n' Text + +'executed if there was no iteration because the sequence was empty.' Text +'\n' Text + +'\n' Text + +'Inside of a ' Text +'`for`' Name.Variable +' loop block you can access some special variables' Text +':' Text +'\n' Text + +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' Variable | Description |' Text +'\n' Text + +'+======================+========================================+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.index`' Name.Variable +' | The current iteration of the loop. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.index0`' Name.Variable +' | The current iteration of the loop, |' Text +'\n' Text + +'|' Operator +' | starting counting by 0. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.revindex`' Name.Variable +' | The number of iterations from the end |' Text +'\n' Text + +'|' Operator +' | of the loop. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.revindex0`' Name.Variable +' | The number of iterations from the end |' Text +'\n' Text + +'|' Operator +' | of the loop, starting counting by 0. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.first`' Name.Variable +' | True if first iteration. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.last`' Name.Variable +' | True if last iteration. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.even`' Name.Variable +' | True if current iteration is even. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.odd`' Name.Variable +' | True if current iteration is odd. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.length`' Name.Variable +' | Total number of items in the sequence. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'|' Operator +' ' Text +'`loop.parent`' Name.Variable +' | The context of the parent loop. |' Text +'\n' Text + +'+----------------------+----------------------------------------+' Text +'\n' Text + +'\n' Text + +"Loops also support recursion. Let's assume you have a sitemap where each item" Text +'\n' Text + +'might have a number of child items. A template for that could look like this' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<' Punctuation +'h1' Name.Tag +'>' Punctuation +'Sitemap\n' Text + +' ' Text +'<' Punctuation +'ul' Name.Tag +' ' Text +'id' Name.Attribute +'=' Operator +'"sitemap"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'item' Name.Variable +' ' Text +'in' Keyword +' ' Text +'sitemap' Name.Variable +' ' Text +'recursive' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'li' Name.Tag +'>' Punctuation +'<' Punctuation +'a' Name.Tag +' ' Text +'href' Name.Attribute +'=' Operator +'"' Literal.String +'{{' Comment.Preproc +' ' Text +'item' Name.Variable +'.url' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'"' Literal.String +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'item' Name.Variable +'.title' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'a' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'item' Name.Variable +'.children' Name.Variable +' ' Text +'%}' Comment.Preproc +'<' Punctuation +'ul' Name.Tag +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'loop' Name.Builtin +'(' Operator +'item' Name.Variable +'.children' Name.Variable +')' Operator +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'ul' Name.Tag +'>' Punctuation +'{%' Comment.Preproc +' ' Text +'endif' Keyword +' ' Text +'%}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'li' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfor' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'ul' Name.Tag +'>' Punctuation +'\n\n' Text + +'What happens here? Basically the first thing that is different to a normal' Text +'\n' Text + +'loop is the additional ' Text +'``' Literal.String +'recursive' Literal.String +'``' Literal.String +' modifier in the ' Text +'`for`' Name.Variable +'-loop declaration.' Text +'\n' Text + +'It tells the template engine that we want recursion. If recursion is enabled' Text +'\n' Text + +'the special ' Text +'`loop`' Name.Variable +' variable is callable. If you call it with a sequence it will' Text +'\n' Text + +'automatically render the loop at that position with the new sequence as argument.' Text +'\n' Text + +'\n' Text + +'Cycling' Generic.Heading +'\n' Text + +'=======' Generic.Heading +'\n' Text + +'\n' Text + +'Sometimes you might want to have different text snippets for each row in a list,' Text +'\n' Text + +'for example to have alternating row colors. You can easily do this by using the' Text +'\n' Text + +'``' Literal.String +'{% cycle %}' Literal.String +'``' Literal.String +' tag' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<' Punctuation +'ul' Name.Tag +' ' Text +'id' Name.Attribute +'=' Operator +'"messages"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'message' Name.Variable +' ' Text +'in' Keyword +' ' Text +'messages' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'li' Name.Tag +' ' Text +'class' Name.Attribute +'=' Operator +'"' Literal.String +'{%' Comment.Preproc +' ' Text +'cycle' Keyword +' ' Text +"'row1'" Literal.String.Single +',' Operator +' ' Text +"'row2'" Literal.String.Single +' ' Text +'%}' Comment.Preproc +'"' Literal.String +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'message' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'li' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfor' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'ul' Name.Tag +'>' Punctuation +'\n\n' Text + +'Each time Jinja encounters a ' Text +'`cycle`' Name.Variable +' tag it will cycle through the list' Text +'\n' Text + +'of given items and return the next one. If you pass it one item jinja assumes' Text +'\n' Text + +'that this item is a sequence from the context and uses this' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<' Punctuation +'li' Name.Tag +' ' Text +'style' Name.Attribute +'=' Operator +'"color: ' Literal.String +'{%' Comment.Preproc +' ' Text +'cycle' Keyword +' ' Text +'rowcolors' Name.Variable +' ' Text +'%}' Comment.Preproc +'"' Literal.String +'>' Punctuation +'...' Text +'<' Punctuation +'/' Punctuation +'li' Name.Tag +'>' Punctuation +'\n\n' Text + +'Conditions' Generic.Heading +'\n' Text + +'==========' Generic.Heading +'\n' Text + +'\n' Text + +'Jinja supports Python-like ' Text +'`if`' Name.Variable +' / ' Text +'`elif`' Name.Variable +' / ' Text +'`else`' Name.Variable +' constructs' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'user' Name.Variable +'.active' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' user ' Other +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.name' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +' is active.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'elif' Keyword +' ' Text +'user' Name.Variable +'.deleted' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' user ' Other +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.name' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +' was deleted some time ago.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'else' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +" i don't know what's wrong with " Other +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.username' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endif' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'If the user is active the first block is rendered. If not and the user was' Text +'\n' Text + +'deleted the second one, in all other cases the third one.' Text +'\n' Text + +'\n' Text + +'You can also use comparison operators' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'amount' Name.Variable +' ' Text +'<' Operator +' ' Text +'0' Literal.Number +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'span' Name.Tag +' ' Text +'style' Name.Attribute +'=' Operator +'"color: red"' Literal.String +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'amount' Name.Variable +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'span' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'else' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'span' Name.Tag +' ' Text +'style' Name.Attribute +'=' Operator +'"color: black"' Literal.String +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'amount' Name.Variable +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'span' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endif' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Text + +'..' Punctuation +' ' Text +'admonition' Operator.Word +'::' Punctuation +' ' Text +'Note' Text +'\n' Text + +'\n' Text + +' Of course you can use ' Text +'`or`' Name.Variable +' / ' Text +'`and`' Name.Variable +' and parentheses to create more complex' Text +'\n' Text + +' conditions, but usually the logic is already handled in the application and' Text +'\n' Text + +" you don't have to create such complex constructs in the template code. However" Text +'\n' Text + +' in some situations it might be a good thing to have the abilities to create' Text +'\n' Text + +' them.' Text +'\n' Text + +'\n' Text + +'Operators' Generic.Heading +'\n' Text + +'=========' Generic.Heading +'\n' Text + +'\n' Text + +'Inside ' Text +'``' Literal.String +'{{ variable }}' Literal.String +'``' Literal.String +' blocks, ' Text +'`if`' Name.Variable +' conditions and many other parts you can' Text +'\n' Text + +'can use expressions. In expressions you can use any of the following operators' Text +':' Text +'\n' Text + +'\n' Text + +' ======= ===================================================================' Text +'\n' Text + +' ' Text +'``' Literal.String +'+' Literal.String +'``' Literal.String +' add the right operand to the left one.' Text +'\n' Text + +' ' Text +'``' Literal.String +'{{ 1 + 2 }}' Literal.String +'``' Literal.String +' would return ' Text +'``' Literal.String +'3' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +' ' Text +'``' Literal.String +'-' Literal.String +'``' Literal.String +' subtract the right operand from the left one.' Text +'\n' Text + +' ' Text +'``' Literal.String +'{{ 1 - 1 }}' Literal.String +'``' Literal.String +' would return ' Text +'``' Literal.String +'0' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +' ' Text +'``' Literal.String +'/' Literal.String +'``' Literal.String +' divide the left operand by the right one.' Text +'\n' Text + +' ' Text +'``' Literal.String +'{{ 1 / 2 }}' Literal.String +'``' Literal.String +' would return ' Text +'``' Literal.String +'0.5' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +' ' Text +'``' Literal.String +'*' Literal.String +'``' Literal.String +' multiply the left operand with the right one.' Text +'\n' Text + +' ' Text +'``' Literal.String +'{{ 2 * 2 }}' Literal.String +'``' Literal.String +' would return ' Text +'``' Literal.String +'4' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +' ' Text +'``' Literal.String +'**' Literal.String +'``' Literal.String +' raise the left operand to the power of the right' Text +'\n' Text + +' operand. ' Text +'``' Literal.String +'{{ 2**3 }}' Literal.String +'``' Literal.String +' would return ' Text +'``' Literal.String +'8' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +' ' Text +'``' Literal.String +'in' Literal.String +'``' Literal.String +' perform sequence membership test. ' Text +'``' Literal.String +'{{ 1 in [1,2,3] }}' Literal.String +'``' Literal.String +' would' Text +'\n' Text + +' return true.' Text +'\n' Text + +' ' Text +'``' Literal.String +'is' Literal.String +'``' Literal.String +' perform a test on the value. See the section about' Text +'\n' Text + +' tests for more information.' Text +'\n' Text + +' ' Text +'``' Literal.String +'|' Literal.String +'``' Literal.String +' apply a filter on the value. See the section about' Text +'\n' Text + +' filters for more information.' Text +'\n' Text + +' ' Text +'``' Literal.String +'and' Literal.String +'``' Literal.String +' return true if the left and the right operand is true.' Text +'\n' Text + +' ' Text +'``' Literal.String +'or' Literal.String +'``' Literal.String +' return true if the left or the right operand is true.' Text +'\n' Text + +' ' Text +'``' Literal.String +'not' Literal.String +'``' Literal.String +' negate a statement (see below)' Text +'\n' Text + +' ' Text +'``' Literal.String +'()' Literal.String +'``' Literal.String +' call a callable' Text +':' Text +' ' Text +'``' Literal.String +'{{ user.get_username() }}' Literal.String +'``' Literal.String +'. Inside of the' Text +'\n' Text + +' parentheses you can use variables' Text +':' Text +' ' Text +'``' Literal.String +'{{ user.get(username) }}' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +' ======= ===================================================================' Text +'\n' Text + +'\n' Text + +'Note that there is no support for any bit operations or something similar.' Text +'\n' Text + +'\n' Text + +'*' Literal.Number +' special note regarding ' Text +'`not`' Name.Variable +':' Text +' The ' Text +'`is`' Name.Variable +' and ' Text +'`in`' Name.Variable +' operators support negation' Text +'\n' Text + +' using an infix notation too' Text +':' Text +' ' Text +'``' Literal.String +'foo is not bar' Literal.String +'``' Literal.String +' and ' Text +'``' Literal.String +'foo not in bar' Literal.String +'``' Literal.String +'\n' Text + +' instead of ' Text +'``' Literal.String +'not foo is bar' Literal.String +'``' Literal.String +' and ' Text +'``' Literal.String +'not foo in bar' Literal.String +'``' Literal.String +'. All other expressions' Text +'\n' Text + +' require a prefix notation' Text +':' Text +' ' Text +'``' Literal.String +'not (foo and bar)' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +'\n' Text + +'Boolean Values' Generic.Heading +'\n' Text + +'==============' Generic.Heading +'\n' Text + +'\n' Text + +'In If-Conditions Jinja performs a boolean check. All empty values (eg' Text +':' Text +' empty' Text +'\n' Text + +'lists ' Text +'``' Literal.String +'[]' Literal.String +'``' Literal.String +', empty dicts ' Text +'``' Literal.String +'{}' Literal.String +'``' Literal.String +' etc) evaluate to ' Text +'`false`' Name.Variable +'. Numbers that are' Text +'\n' Text + +'equal to ' Text +'`0`' Name.Variable +'/' Text +'`0.00`' Name.Variable +' are considered ' Text +'`false`' Name.Variable +' too. The boolean value of other' Text +'\n' Text + +'objects depends on the behavior the application developer gave it. Usually' Text +'\n' Text + +'items are ' Text +'`true`' Name.Variable +'.' Text +'\n' Text + +'\n' Text + +'Here some examples that should explain it' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'[' Operator +']' Operator +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +" will always be false because it's an empty list\n\n" Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'{' Operator +'}' Operator +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' false too.\n\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'[' Operator +"'foo'" Literal.String.Single +']' Operator +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' this is true. Because the list is not empty.\n\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'"foobar"' Literal.String.Double +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' this is also true because the string is not empty.\n\n' Other + +'Slicing' Generic.Heading +'\n' Text + +'=======' Generic.Heading +'\n' Text + +'\n' Text + +'Some objects support slicing operations. For example lists' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'item' Name.Variable +' ' Text +'in' Keyword +' ' Text +'items' Name.Variable +'[' Operator +':' Operator +'5' Literal.Number +']' Operator +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' This will only iterate over the first 5 items of the list\n\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'item' Name.Variable +' ' Text +'in' Keyword +' ' Text +'items' Name.Variable +'[' Operator +'5' Literal.Number +':' Operator +'1' Literal.Number +'0' Literal.Number +']' Operator +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' This will only iterate from item 5 to 10.\n\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'item' Name.Variable +' ' Text +'in' Keyword +' ' Text +'items' Name.Variable +'[' Operator +':' Operator +'1' Literal.Number +'0' Literal.Number +':' Operator +'2' Literal.Number +']' Operator +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' This will only yield items from start to ten and only returing\n' Other + +' ' Text +' even items.\n\n' Other + +'For more informations about slicing have a look at the ' Text +'`slicing chapter`_' Literal.String +'\n' Text + +'in the "Dive into Python" e-book.' Text +'\n' Text + +'\n' Text + +'Macros' Generic.Heading +'\n' Text + +'======' Generic.Heading +'\n' Text + +'\n' Text + +'If you want to use a partial template in more than one place, you might want to' Text +'\n' Text + +'create a macro from it' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'macro' Keyword +' ' Text +'show_user' Name.Variable +' ' Text +'user' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'h1' Name.Tag +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.name' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'h1' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'div' Name.Tag +' ' Text +'class' Name.Attribute +'=' Operator +'"test"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{{' Comment.Preproc +' ' Text +'user' Name.Variable +'.description' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'div' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endmacro' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Text + +'Now you can use it from everywhere in the code by passing it an item' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n \n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'user' Name.Variable +' ' Text +'in' Keyword +' ' Text +'users' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'show_user' Name.Variable +'(' Operator +'user' Name.Variable +')' Operator +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfor' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'You can also specify more than one value' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'macro' Keyword +' ' Text +'show_dialog' Name.Variable +' ' Text +'title' Name.Variable +',' Operator +' ' Text +'text' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'div' Name.Tag +' ' Text +'class' Name.Attribute +'=' Operator +'"dialog"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'h1' Name.Tag +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'title' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'h1' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'div' Name.Tag +' ' Text +'class' Name.Attribute +'=' Operator +'"test"' Literal.String +'>' Punctuation +'{{' Comment.Preproc +' ' Text +'text' Name.Variable +'|' Operator +'e' Name.Function +' ' Text +'}}' Comment.Preproc +'<' Punctuation +'/' Punctuation +'div' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'div' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endmacro' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'show_dialog' Name.Variable +'(' Operator +"'Warning'" Literal.String.Single +',' Operator +' ' Text +"'something went wrong i guess'" Literal.String.Single +')' Operator +' ' Text +'}}' Comment.Preproc +'\n\n' Text + +'Inheritance' Generic.Heading +'\n' Text + +'===========' Generic.Heading +'\n' Text + +'\n' Text + +'The most powerful part of Jinja is template inheritance. Template inheritance' Text +'\n' Text + +'allows you to build a base "skeleton" template that contains all the common' Text +'\n' Text + +'elements of your site and defines ' Text +'**blocks**' Generic.Strong +' that child templates can override.' Text +'\n' Text + +'\n' Text + +"Sounds complicated but is very basic. It's easiest to understand it by starting" Text +'\n' Text + +'with an example.' Text +'\n' Text + +'\n' Text + +'Base Template' Generic.Heading +'\n' Text + +'-------------' Generic.Heading +'\n' Text + +'\n' Text + +"This template, which we'll call " Text +'``' Literal.String +'base.html' Literal.String +'``' Literal.String +', defines a simple HTML skeleton' Text +'\n' Text + +"document that you might use for a simple two-column page. It's the job of" Text +'\n' Text + +'"child" templates to fill the empty blocks with content' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n' Comment.Preproc + +' ' Text +' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'html' Name.Tag +' ' Text +'xmlns' Name.Attribute +'=' Operator +'"http://www.w3.org/1999/xhtml"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'head' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'link' Name.Tag +' ' Text +'rel' Name.Attribute +'=' Operator +'"stylesheet"' Literal.String +' ' Text +'href' Name.Attribute +'=' Operator +'"style.css"' Literal.String +' ' Text +'/' Punctuation +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'title' Name.Tag +'>' Punctuation +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'title' Name.Variable +' ' Text +'%}' Comment.Preproc +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +' - My Webpage' Text +'<' Punctuation +'/' Punctuation +'title' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'html_head' Name.Variable +' ' Text +'%}' Comment.Preproc +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'head' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'body' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'div' Name.Tag +' ' Text +'id' Name.Attribute +'=' Operator +'"content"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'content' Name.Variable +' ' Text +'%}' Comment.Preproc +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'div' Name.Tag +'>' Punctuation +'\n\n' Text + +' ' Text +' ' Text +'<' Punctuation +'div' Name.Tag +' ' Text +'id' Name.Attribute +'=' Operator +'"footer"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'footer' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'©' Name.Entity +' Copyright 2006 by ' Text +'<' Punctuation +'a' Name.Tag +' ' Text +'href' Name.Attribute +'=' Operator +'"http://mydomain.tld"' Literal.String +'>' Punctuation +'myself' Text +'<' Punctuation +'/' Punctuation +'a' Name.Tag +'>' Punctuation +'.\n' Text + +' ' Text +' ' Text +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'div' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'<' Punctuation +'/' Punctuation +'body' Name.Tag +'>' Punctuation +'\n\n' Text + +'In this example, the ' Text +'``' Literal.String +'{% block %}' Literal.String +'``' Literal.String +' tags define four blocks that child templates' Text +'\n' Text + +'can fill in. All the ' Text +'`block`' Name.Variable +' tag does is to tell the template engine that a' Text +'\n' Text + +'child template may override those portions of the template.' Text +'\n' Text + +'\n' Text + +'Child Template' Generic.Heading +'\n' Text + +'--------------' Generic.Heading +'\n' Text + +'\n' Text + +'A child template might look like this' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'html+jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'extends' Keyword +' ' Text +'"base.html"' Literal.String.Double +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'title' Name.Variable +' ' Text +'%}' Comment.Preproc +'Index' Text +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'html_head' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'style' Name.Tag +' ' Text +'type' Name.Attribute +'=' Operator +'"text/css"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'.' Punctuation +'important' Name.Class +' ' Text +'{' Punctuation +'\n' Text + +' ' Text +' ' Text +'color' Keyword +':' Punctuation +' ' Text +'#336699' Literal.Number.Hex +';' Punctuation +'\n' Text + +' ' Text +' ' Text +'}' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'style' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'block' Keyword +' ' Text +'content' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'h1' Name.Tag +'>' Punctuation +'Index' Text +'<' Punctuation +'/' Punctuation +'h1' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +' ' Text +'<' Punctuation +'p' Name.Tag +' ' Text +'class' Name.Attribute +'=' Operator +'"important"' Literal.String +'>' Punctuation +'\n' Text + +' ' Text +' Welcome on my awsome homepage.\n' Text + +' ' Text +' ' Text +'<' Punctuation +'/' Punctuation +'p' Name.Tag +'>' Punctuation +'\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endblock' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Text + +'The ' Text +'``' Literal.String +'{% extends %}' Literal.String +'``' Literal.String +' tag is the key here. It tells the template engine that' Text +'\n' Text + +'this template "extends" another template. When the template system evaluates' Text +'\n' Text + +'this template, first it locates the parent.' Text +'\n' Text + +'\n' Text + +'The filename of the template depends on the template loader. For example the' Text +'\n' Text + +'``' Literal.String +'FileSystemLoader' Literal.String +'``' Literal.String +' allows you to access other templates by giving the' Text +'\n' Text + +'filename. You can access templates in subdirectories with an slash' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'extends' Keyword +' ' Text +'"layout/default.html"' Literal.String.Double +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'But this behavior can depend on the application using Jinja.' Text +'\n' Text + +'\n' Text + +"Note that since the child template didn't define the " Text +'``' Literal.String +'footer' Literal.String +'``' Literal.String +' block, the' Text +'\n' Text + +'value from the parent template is used instead.' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'admonition' Operator.Word +'::' Punctuation +' ' Text +'Note' Text +'\n' Text + +'\n' Text + +" You can't define multiple " Text +'``' Literal.String +'{% block %}' Literal.String +'``' Literal.String +' tags with the same name in the' Text +'\n' Text + +' same template. This limitation exists because a block tag works in "both"' Text +'\n' Text + +" directions. That is, a block tag doesn't just provide a hole to fill - it" Text +'\n' Text + +' also defines the content that fills the hole in the ' Text +'*parent*' Generic.Emph +'. If there were' Text +'\n' Text + +' two similarly-named ' Text +'``' Literal.String +'{% block %}' Literal.String +'``' Literal.String +" tags in a template, that template's" Text +'\n' Text + +" parent wouldn't know which one of the blocks' content to use." Text +'\n' Text + +'\n' Text + +'Template Inclusion' Generic.Heading +'\n' Text + +'==================' Generic.Heading +'\n' Text + +'\n' Text + +'You can load another template at a given position using ' Text +'``' Literal.String +'{% include %}' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +"Usually it's a better idea to use inheritance but if you for example want to" Text +'\n' Text + +'load macros, ' Text +'`include`' Name.Variable +' works better than ' Text +'`extends`' Name.Variable +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'include' Keyword +' ' Text +'"myhelpers.html"' Literal.String.Double +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'my_helper' Name.Variable +'(' Operator +'"foo"' Literal.String.Double +')' Operator +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'If you define a macro called ' Text +'``' Literal.String +'my_helper' Literal.String +'``' Literal.String +' in ' Text +'``' Literal.String +'myhelpers.html' Literal.String +'``' Literal.String +', you can now' Text +'\n' Text + +'use it from the template as shown above.' Text +'\n' Text + +'\n' Text + +'Filtering Blocks' Generic.Heading +'\n' Text + +'================' Generic.Heading +'\n' Text + +'\n' Text + +'Sometimes it could be a good idea to filter a complete block of text. For' Text +'\n' Text + +'example, if you want to escape some html code' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'filter' Keyword +' ' Text +'escape' Name.Function +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' <html>\n' Other + +' ' Text +' <code>goes here</code>\n' Other + +' ' Text +' </html>\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfilter' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'Of course you can chain filters too' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'filter' Keyword +' ' Text +'lower' Name.Function +'|' Operator +'escape' Name.Function +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' <B>SOME TEXT</B>\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfilter' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'returns ' Text +'``' Literal.String +'"<b>some text</b>"' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +'\n' Text + +'Defining Variables' Generic.Heading +'\n' Text + +'==================' Generic.Heading +'\n' Text + +'\n' Text + +'You can also define variables in the namespace using the ' Text +'``' Literal.String +'{% set %}' Literal.String +'``' Literal.String +' tag' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'set' Keyword +' ' Text +'foo' Name.Variable +' ' Text +'=' Operator +' ' Text +"'foobar'" Literal.String.Single +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'foo' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'This should ouput ' Text +'``' Literal.String +'foobar' Literal.String +'``' Literal.String +'.' Text +'\n' Text + +'\n' Text + +'Scopes' Generic.Heading +'\n' Text + +'======' Generic.Heading +'\n' Text + +'\n' Text + +'Jinja has multiple scopes. A scope is something like a new transparent foil on' Text +'\n' Text + +'a stack of foils. You can only write to the outermost foil but read all of them' Text +'\n' Text + +'since you can look through them. If you remove the top foil all data on that' Text +'\n' Text + +'foil disappears. Some tags in Jinja add a new layer to the stack. Currently' Text +'\n' Text + +'these are ' Text +'`block`' Name.Variable +', ' Text +'`for`' Name.Variable +', ' Text +'`macro`' Name.Variable +' and ' Text +'`filter`' Name.Variable +'. This means that variables and' Text +'\n' Text + +'other elements defined inside a macro, loop or some of the other tags listed' Text +'\n' Text + +'above will be only available in that block. Here an example' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'macro' Keyword +' ' Text +'angryhello' Name.Variable +' ' Text +'name' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' ' Other +'{%' Comment.Preproc +' ' Text +'set' Keyword +' ' Text +'angryname' Name.Variable +' ' Text +'=' Operator +' ' Text +'name' Name.Variable +'|' Operator +'upper' Name.Function +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' Hello ' Other +'{{' Comment.Preproc +' ' Text +'name' Name.Variable +' ' Text +'}}' Comment.Preproc +'. Hello ' Other +'{{' Comment.Preproc +' ' Text +'name' Name.Variable +' ' Text +'}}' Comment.Preproc +'!\n' Other + +' ' Text +' HELLO ' Other +'{{' Comment.Preproc +' ' Text +'angryname' Name.Variable +' ' Text +'}}' Comment.Preproc +'!!!!!!111\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endmacro' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'The variable ' Text +'``' Literal.String +'angryname' Literal.String +'``' Literal.String +' just exists inside the macro, not outside it.' Text +'\n' Text + +'\n' Text + +'Defined macros appear on the context as variables. Because of this, they are' Text +'\n' Text + +'affected by the scoping too. A macro defined inside of a macro is just available' Text +'\n' Text + +"in those two macros (the macro itself and the macro it's defined in). For " Text +'`set`' Name.Variable +'\n' Text + +'and ' Text +'`macro`' Name.Variable +' two additional rules exist' Text +':' Text +' If a macro is defined in an extended' Text +'\n' Text + +'template but outside of a visible block (thus outside of any block) will be' Text +'\n' Text + +'available in all blocks below. This allows you to use ' Text +'`include`' Name.Variable +' statements to' Text +'\n' Text + +'load often used macros at once.' Text +'\n' Text + +'\n' Text + +'Undefined Variables' Generic.Heading +'\n' Text + +'===================' Generic.Heading +'\n' Text + +'\n' Text + +'If you have already worked with python you probably know about the fact that' Text +'\n' Text + +'undefined variables raise an exception. This is different in Jinja. There is a' Text +'\n' Text + +'special value called ' Text +'`undefined`' Name.Variable +' that represents values that do not exist.' Text +'\n' Text + +'\n' Text + +'This special variable works complete different from any variables you maybe' Text +'\n' Text + +'know. If you print it using ' Text +'``' Literal.String +'{{ variable }}' Literal.String +'``' Literal.String +" it will not appear because it's" Text +'\n' Text + +'literally empty. If you try to iterate over it, it will work. But no items' Text +'\n' Text + +'are returned. Comparing this value to any other value results in ' Text +'`false`' Name.Variable +'.' Text +'\n' Text + +'Even if you compare it to itself' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'undefined' Name.Variable +' ' Text +'==' Operator +' ' Text +'undefined' Name.Variable +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' will return false. Not even undefined is undefined :)\n' Other + +' ' Text +' Use `is defined` / `is not defined`:\n\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'undefined' Name.Variable +' ' Text +'is' Keyword +' ' Text +'not' Keyword +' ' Text +'defined' Name.Function +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' will return true.\n\n' Other + +'There are also some additional rules regarding this special value. Any' Text +'\n' Text + +'mathematical operators (' Text +'``' Literal.String +'+' Literal.String +'``' Literal.String +', ' Text +'``' Literal.String +'-' Literal.String +'``' Literal.String +', ' Text +'``' Literal.String +'*' Literal.String +'``' Literal.String +', ' Text +'``' Literal.String +'/' Literal.String +'``' Literal.String +') return the operand' Text +'\n' Text + +'as result' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'undefined' Name.Variable +' ' Text +'+' Operator +' ' Text +'"foo"' Literal.String.Double +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' returns "foo"\n\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'undefined' Name.Variable +' ' Text +'-' Operator +' ' Text +'4' Literal.Number +'2' Literal.Number +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' returns 42. Note: not -42!\n\n' Other + +'In any expression ' Text +'`undefined`' Name.Variable +' evaluates to ' Text +'`false`' Name.Variable +'. It has no length, all' Text +'\n' Text + +'attribute calls return undefined, calling too' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'undefined' Name.Variable +'.attribute' Name.Variable +'(' Operator +')' Operator +'.attribute_too' Name.Variable +'[' Operator +'4' Literal.Number +'2' Literal.Number +']' Operator +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +' still returns `undefined`.\n\n' Other + +'Escaping' Generic.Heading +'\n' Text + +'========' Generic.Heading +'\n' Text + +'\n' Text + +'Sometimes you might want to add Jinja syntax elements into the template' Text +'\n' Text + +'without executing them. In that case you have quite a few possibilities.' Text +'\n' Text + +'\n' Text + +'For small parts this might be a good way' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{{' Comment.Preproc +' ' Text +'"{{ foo }} is variable syntax and {% foo %} is block syntax"' Literal.String.Double +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'When you have multiple elements you can use the ' Text +'``' Literal.String +'raw' Literal.String +'``' Literal.String +' block' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'raw' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Text + +' ' Text +' Filtering blocks works like this in Jinja:\n' Text + +' ' Text +' {% filter escape %}\n' Text + +' ' Text +' <html>\n' Text + +' ' Text +' <code>goes here</code>\n' Text + +' ' Text +' </html>\n' Text + +' ' Text +' {% endfilter %}\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'endraw' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'Reserved Keywords' Generic.Heading +'\n' Text + +'=================' Generic.Heading +'\n' Text + +'\n' Text + +'Jinja has some keywords you cannot use a variable names. This limitation' Text +'\n' Text + +"exists to make look coherent. Syntax highlighters won't mess things up and" Text +'\n' Text + +"you will don't have unexpected output." Text +'\n' Text + +'\n' Text + +'The following keywords exist and cannot be used as identifiers' Text +':' Text +'\n' Text + +'\n' Text + +' ' Text +'`and`' Name.Variable +', ' Text +'`block`' Name.Variable +', ' Text +'`cycle`' Name.Variable +', ' Text +'`elif`' Name.Variable +', ' Text +'`else`' Name.Variable +', ' Text +'`endblock`' Name.Variable +', ' Text +'`endfilter`' Name.Variable +',' Text +'\n' Text + +' ' Text +'`endfor`' Name.Variable +', ' Text +'`endif`' Name.Variable +', ' Text +'`endmacro`' Name.Variable +', ' Text +'`endraw`' Name.Variable +', ' Text +'`endtrans`' Name.Variable +', ' Text +'`extends`' Name.Variable +', ' Text +'`filter`' Name.Variable +',' Text +'\n' Text + +' ' Text +'`for`' Name.Variable +', ' Text +'`if`' Name.Variable +', ' Text +'`in`' Name.Variable +', ' Text +'`include`' Name.Variable +', ' Text +'`is`' Name.Variable +', ' Text +'`macro`' Name.Variable +', ' Text +'`not`' Name.Variable +', ' Text +'`or`' Name.Variable +', ' Text +'`pluralize`' Name.Variable +',' Text +'\n' Text + +' ' Text +'`raw`' Name.Variable +', ' Text +'`recursive`' Name.Variable +', ' Text +'`set`' Name.Variable +', ' Text +'`trans`' Name.Variable +'\n' Text + +'\n' Text + +'If you want to use such a name you have to prefix or suffix it or use' Text +'\n' Text + +'alternative names' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'for' Keyword +' ' Text +'macro_' Name.Variable +' ' Text +'in' Keyword +' ' Text +'macros' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'macro_' Name.Variable +'(' Operator +"'foo'" Literal.String.Single +')' Operator +' ' Text +'}}' Comment.Preproc +'\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endfor' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'If future Jinja releases add new keywords those will be "light" keywords which' Text +'\n' Text + +"means that they won't raise an error for several releases but yield warnings" Text +'\n' Text + +"on the application side. But it's very unlikely that new keywords will be" Text +'\n' Text + +'added.' Text +'\n' Text + +'\n' Text + +'Internationalization' Generic.Heading +'\n' Text + +'====================' Generic.Heading +'\n' Text + +'\n' Text + +'If the application is configured for i18n, you can define translatable blocks' Text +'\n' Text + +'for translators using the ' Text +'`trans`' Name.Variable +' tag or the special underscore function' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'trans' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' this is a translatable block\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endtrans' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'trans' Keyword +' ' Text +'"This is a translatable string"' Literal.String.Double +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +' ' Text +'{{' Comment.Preproc +' ' Text +'_' Keyword.Pseudo +'(' Operator +'"This is a translatable string"' Literal.String.Double +')' Operator +' ' Text +'}}' Comment.Preproc +'\n\n' Other + +'The latter one is useful if you want translatable arguments for filters etc.' Text +'\n' Text + +'\n' Text + +'If you want to have plural forms too, use the ' Text +'`pluralize`' Name.Variable +' block' Text +':' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'trans' Keyword +' ' Text +'users' Name.Variable +'=' Operator +'users' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' One user found.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'pluralize' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'users' Name.Variable +' ' Text +'}}' Comment.Preproc +' users found.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endtrans' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'trans' Keyword +' ' Text +'first' Name.Variable +'=' Operator +'(' Operator +'users' Name.Variable +'|' Operator +'first' Name.Function +')' Operator +'.username' Name.Variable +'|' Operator +'escape' Name.Function +',' Operator +' ' Text +'user' Name.Variable +'=' Operator +'users' Name.Variable +'|' Operator +'length' Name.Function +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' one user ' Other +'{{' Comment.Preproc +' ' Text +'first' Name.Variable +' ' Text +'}}' Comment.Preproc +' found.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'pluralize' Keyword +' ' Text +'users' Name.Variable +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'users' Name.Variable +' ' Text +'}}' Comment.Preproc +' users found, the first one is called ' Other +'{{' Comment.Preproc +' ' Text +'first' Name.Variable +' ' Text +'}}' Comment.Preproc +'.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endtrans' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'If you have multiple arguments, the first one is assumed to be the indicator (the' Text +'\n' Text + +'number that is used to determine the correct singular or plural form. If you' Text +'\n' Text + +"don't have the indicator variable on position 1 you have to tell the " Text +'`pluralize`' Name.Variable +'\n' Text + +'tag the correct variable name.' Text +'\n' Text + +'\n' Text + +'Inside translatable blocks you cannot use blocks or expressions (however you can' Text +'\n' Text + +'still use the ' Text +'``' Literal.String +'raw' Literal.String +'``' Literal.String +' block which will work as expected). The variable' Text +'\n' Text + +'print syntax (' Text +'``' Literal.String +'{{ variablename }}' Literal.String +'``' Literal.String +') is the only way to insert the variables' Text +'\n' Text + +'defined in the ' Text +'``' Literal.String +'trans' Literal.String +'``' Literal.String +' header. Filters must be applied in the header.' Text +'\n' Text + +'\n' Text + +'..' Punctuation +' ' Text +'admonition' Operator.Word +'::' Punctuation +' ' Text +'note' Text +'\n' Text + +'\n' Text + +' Please make sure that you always use pluralize blocks where required.' Text +'\n' Text + +' Many languages have more complex plural forms than the English language.' Text +'\n' Text + +' ' Text +'\n' Text + +' Never try to workaround that issue by using something like this' Text +':' Text +'\n' Text + +'\n' Text + +' ..' Punctuation +' ' Text +'sourcecode' Operator.Word +'::' Punctuation +' ' Text +'jinja' Keyword +'\n\n' Text + +' ' Text +'{%' Comment.Preproc +' ' Text +'if' Keyword +' ' Text +'count' Name.Variable +' ' Text +'!=' Operator +' ' Text +'1' Literal.Number +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' ' Other +'{{' Comment.Preproc +' ' Text +'count' Name.Variable +' ' Text +'}}' Comment.Preproc +' users found.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'else' Keyword +' ' Text +'%}' Comment.Preproc +'\n' Other + +' ' Text +' one user found.\n' Other + +' ' Text +'{%' Comment.Preproc +' ' Text +'endif' Keyword +' ' Text +'%}' Comment.Preproc +'\n\n' Other + +'..' Punctuation +' ' Text +'_slicing chapter:' Name.Tag +' http' Text +':' Text +'//diveintopython.org/native_data_types/lists.html#odbchelper.list.slice' Text +'\n' Text + +'..' Punctuation +' ' Text +'_range function:' Name.Tag +' http' Text +':' Text +'//docs.python.org/tut/node6.html#SECTION006300000000000000000' Text +'\n' Text |
