Browse files

refactored documentation

  • Loading branch information...
1 parent d65366e commit b096e21daa6647cd23063c3a4e4280ad81df8f84 @fabpot committed Sep 26, 2011
Showing with 1,733 additions and 1,301 deletions.
  1. +11 −0 doc/filters/capitalize.rst
  2. +34 −0 doc/filters/date.rst
  3. +18 −0 doc/filters/default.rst
  4. +30 −0 doc/filters/escape.rst
  5. +16 −0 doc/filters/format.rst
  6. +25 −0 doc/filters/index.rst
  7. +18 −0 doc/filters/join.rst
  8. +8 −0 doc/filters/json_encode.rst
  9. +11 −0 doc/filters/keys.rst
  10. +12 −0 doc/filters/length.rst
  11. +10 −0 doc/filters/lower.rst
  12. +12 −0 doc/filters/merge.rst
  13. +12 −0 doc/filters/raw.rst
  14. +14 −0 doc/filters/replace.rst
  15. +13 −0 doc/filters/reverse.rst
  16. +17 −0 doc/filters/sort.rst
  17. +16 −0 doc/filters/striptags.rst
  18. +11 −0 doc/filters/title.rst
  19. +10 −0 doc/filters/upper.rst
  20. +8 −0 doc/filters/url_encode.rst
  21. +18 −0 doc/functions/attribute.rst
  22. +15 −0 doc/functions/block.rst
  23. +8 −0 doc/functions/constant.rst
  24. +20 −0 doc/functions/cycle.rst
  25. +12 −0 doc/functions/index.rst
  26. +20 −0 doc/functions/parent.rst
  27. +38 −0 doc/functions/range.rst
  28. +4 −0 doc/index.rst
  29. +43 −0 doc/tags/autoescape.rst
  30. +11 −0 doc/tags/block.rst
  31. +188 −0 doc/tags/extends.rst
  32. +21 −0 doc/tags/filter.rst
  33. +126 −0 doc/tags/for.rst
  34. +8 −0 doc/tags/from.rst
  35. +33 −0 doc/tags/if.rst
  36. +79 −0 doc/tags/import.rst
  37. +83 −0 doc/tags/include.rst
  38. +20 −0 doc/tags/index.rst
  39. +91 −0 doc/tags/macro.rst
  40. +16 −0 doc/tags/raw.rst
  41. +32 −0 doc/tags/set.rst
  42. +14 −0 doc/tags/spaceless.rst
  43. +123 −0 doc/tags/use.rst
  44. +302 −1,301 doc/templates.rst
  45. +11 −0 doc/tests/constant.rst
  46. +17 −0 doc/tests/defined.rst
  47. +10 −0 doc/tests/divisibleby.rst
  48. +11 −0 doc/tests/empty.rst
  49. +10 −0 doc/tests/even.rst
  50. +14 −0 doc/tests/index.rst
  51. +8 −0 doc/tests/none.rst
  52. +10 −0 doc/tests/odd.rst
  53. +11 −0 doc/tests/sameas.rst
View
11 doc/filters/capitalize.rst
@@ -0,0 +1,11 @@
+``capitalize``
+==============
+
+The ``capitalize`` filter capitalizes a value. The first character will be
+uppercase, all others lowercase:
+
+.. code-block:: jinja
+
+ {{ 'my first car'|capitalize }}
+
+ {# outputs 'My first car' #}
View
34 doc/filters/date.rst
@@ -0,0 +1,34 @@
+``date``
+========
+
+.. versionadded:: 1.1
+ The timezone support has been added in Twig 1.1.
+
+The ``date`` filter formats a date to a given format:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("m/d/Y") }}
+
+The ``date`` filter accepts any date format supported by `date`_ and
+`DateTime`_ instances. For instance, to display the current date, filter the
+word "now":
+
+.. code-block:: jinja
+
+ {{ "now"|date("m/d/Y") }}
+
+To escape words and characters in the date format use ``\\`` in front of each character:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("F jS \\a\\t g:ia") }}
+
+You can also specify a timezone:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("m/d/Y", "Europe/Paris") }}
+
+.. _`date`: http://www.php.net/date
+.. _`DateTime`: http://www.php.net/manual/en/datetime.construct.php
View
18 doc/filters/default.rst
@@ -0,0 +1,18 @@
+``default``
+===========
+
+The ``default`` filter returns the passed default value if the value is
+undefined or empty, otherwise the value of the variable:
+
+.. code-block:: jinja
+
+ {{ var|default('var is not defined') }}
+
+ {{ var.foo|default('foo item on var is not defined') }}
+
+ {{ ''|default('passed var is empty') }}
+
+.. note::
+
+ Read the documentation for the :doc:`defined<../tests/defined>` and
+ :doc:`empty<../tests/empty>` tests to learn more about their semantics.
View
30 doc/filters/escape.rst
@@ -0,0 +1,30 @@
+``escape``
+==========
+
+The ``escape`` filter converts the characters ``&``, ``<``, ``>``, ``'``, and
+``"`` in strings to HTML-safe sequences. Use this if you need to display text
+that might contain such characters in HTML:
+
+.. code-block:: jinja
+
+ {{ user.username|escape }}
+
+For convenience, the ``e`` filter is defined as an alias:
+
+.. code-block:: jinja
+
+ {{ user.username|e }}
+
+The ``escape`` filter can also be used in another context than HTML; for
+instance, to escape variables included in a JavaScript:
+
+.. code-block:: jinja
+
+ {{ user.username|escape('js') }}
+ {{ user.username|e('js') }}
+
+.. note::
+
+ Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function.
+
+.. _`htmlspecialchars`: http://php.net/htmlspecialchars
View
16 doc/filters/format.rst
@@ -0,0 +1,16 @@
+``format``
+==========
+
+The ``format`` filter formats a given string by replacing the placeholders
+(placeholders follows the `printf`_ notation):
+
+.. code-block:: jinja
+
+ {{ "I like %s and %s."|format(foo, "bar") }}
+
+ {# returns I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+.. _`printf`: http://www.php.net/printf
+
+.. seealso:: :doc:`replace<replace>`
View
25 doc/filters/index.rst
@@ -0,0 +1,25 @@
+Filters
+=======
+
+.. toctree::
+ :maxdepth: 1
+
+ date
+ format
+ replace
+ url_encode
+ json_encode
+ title
+ capitalize
+ upper
+ lower
+ striptags
+ join
+ reverse
+ length
+ sort
+ default
+ keys
+ escape
+ raw
+ merge
View
18 doc/filters/join.rst
@@ -0,0 +1,18 @@
+``join``
+========
+
+The ``join`` filter returns a string which is the concatenation of the items
+of a sequence:
+
+.. code-block:: jinja
+
+ {{ [1, 2, 3]|join }}
+ {# returns 123 #}
+
+The separator between elements is an empty string per default, but you can
+define it with the optional first parameter:
+
+.. code-block:: jinja
+
+ {{ [1, 2, 3]|join('|') }}
+ {# returns 1|2|3 #}
View
8 doc/filters/json_encode.rst
@@ -0,0 +1,8 @@
+``json_encode``
+===============
+
+The ``json_encode`` filter returns the JSON representation of a string:
+
+.. code-block:: jinja
+
+ {{ data|json_encode() }}
View
11 doc/filters/keys.rst
@@ -0,0 +1,11 @@
+``keys``
+========
+
+The ``keys`` filter returns the keys of an array. It is useful when you want to
+iterate over the keys of an array:
+
+.. code-block:: jinja
+
+ {% for key in array|keys %}
+ ...
+ {% endfor %}
View
12 doc/filters/length.rst
@@ -0,0 +1,12 @@
+``length``
+==========
+
+The ``length`` filters returns the number of items of a sequence or mapping, or
+the length of a string:
+
+.. code-block:: jinja
+
+ {% if users|length > 10 %}
+ ...
+ {% endif %}
+
View
10 doc/filters/lower.rst
@@ -0,0 +1,10 @@
+``lower``
+=========
+
+The ``lower`` filter converts a value to lowercase:
+
+.. code-block:: jinja
+
+ {{ 'WELCOME'|lower }}
+
+ {# outputs 'welcome' #}
View
12 doc/filters/merge.rst
@@ -0,0 +1,12 @@
+``merge``
+=========
+
+The ``merge`` filter merges an array or a hash with the given value:
+
+.. code-block:: jinja
+
+ {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
+
+ {% set items = items|merge({ 'peugeot': 'car' }) %}
+
+ {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
View
12 doc/filters/raw.rst
@@ -0,0 +1,12 @@
+``raw``
+=======
+
+The ``raw`` filter marks the value as being "safe", which means that in an
+environment with automatic escaping enabled this variable will not be escaped
+if ``raw`` is the last filter applied to it:
+
+.. code-block:: jinja
+
+ {% autoescape true %}
+ {{ var|raw }} {# var won't be escaped #}
+ {% endautoescape %}
View
14 doc/filters/replace.rst
@@ -0,0 +1,14 @@
+``replace``
+===========
+
+The ``replace`` filter formats a given string by replacing the placeholders
+(placeholders are free-form):
+
+.. code-block:: jinja
+
+ {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }}
+
+ {# returns I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+.. seealso:: :doc:`format<format>`
View
13 doc/filters/reverse.rst
@@ -0,0 +1,13 @@
+``reverse``
+===========
+
+The ``reverse`` filter reverses an array (or an object if it implements the
+`Iterator`_ interface):
+
+.. code-block:: jinja
+
+ {% for use in users|reverse %}
+ ...
+ {% endfor %}
+
+.. _`Iterator`: http://fr.php.net/manual/en/class.iterator.php
View
17 doc/filters/sort.rst
@@ -0,0 +1,17 @@
+``sort``
+========
+
+The ``sort`` filter sorts an array:
+
+.. code-block:: jinja
+
+ {% for use in users|sort %}
+ ...
+ {% endfor %}
+
+.. note::
+
+ Internally, Twig uses the PHP `asort`_ function to maintain index
+ association.
+
+.. _`asort`: http://php.net/asort
View
16 doc/filters/striptags.rst
@@ -0,0 +1,16 @@
+``striptags``
+=============
+
+The ``striptags`` filter strips SGML/XML tags and replace adjacent whitespace
+by one space:
+
+.. code-block:: jinja
+
+ {% some_html|striptags %}
+
+.. note::
+
+ Internally, Twig uses the PHP `strip_tags`_ function to maintain index
+ association.
+
+.. _`strip_tags`: http://php.net/strip_tags
View
11 doc/filters/title.rst
@@ -0,0 +1,11 @@
+``title``
+=========
+
+The ``title`` filter returns a titlecased version of the value. Words will
+start with uppercase letters, all remaining characters are lowercase:
+
+.. code-block:: jinja
+
+ {{ 'my first car'|title }}
+
+ {# outputs 'My First Car' #}
View
10 doc/filters/upper.rst
@@ -0,0 +1,10 @@
+``upper``
+=========
+
+The ``upper`` filter converts a value to uppercase:
+
+.. code-block:: jinja
+
+ {{ 'welcome'|upper }}
+
+ {# outputs 'WELCOME' #}
View
8 doc/filters/url_encode.rst
@@ -0,0 +1,8 @@
+``url_encode``
+==============
+
+The ``url_encode`` filter URL encodes a given string:
+
+.. code-block:: jinja
+
+ {{ data|url_encode() }}
View
18 doc/functions/attribute.rst
@@ -0,0 +1,18 @@
+``attribute``
+=============
+
+.. versionadded:: 1.2
+ The ``attribute`` function was added in Twig 1.2.
+
+``attribute`` can be used to access a "dynamic" attribute of a variable:
+
+.. code-block:: jinja
+
+ {{ attribute(object, method) }}
+ {{ attribute(object, method, arguments) }}
+ {{ attribute(array, item) }}
+
+.. note::
+
+ The resolution algorithm is the same as the one used for the ``.``
+ notation, except that the item can be any valid expression.
View
15 doc/functions/block.rst
@@ -0,0 +1,15 @@
+``block``
+=========
+
+When a template uses inheritance and if you want to print a block multiple
+times, use the ``block`` function:
+
+.. code-block:: jinja
+
+ <title>{% block title %}{% endblock %}</title>
+
+ <h1>{{ block('title') }}</h1>
+
+ {% block body %}{% endblock %}
+
+.. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>`
View
8 doc/functions/constant.rst
@@ -0,0 +1,8 @@
+``constant``
+============
+
+``constant`` returns the constant value for a given string:
+
+.. code-block:: jinja
+
+ {{ some_date|date(constant('DATE_W3C')) }}
View
20 doc/functions/cycle.rst
@@ -0,0 +1,20 @@
+``cycle``
+=========
+
+The ``cycle`` function cycles on an array of values:
+
+.. code-block:: jinja
+
+ {% for i in 0..10 %}
+ {{ cycle(['odd', 'even'], i) }}
+ {% endfor %}
+
+The array can contain any number of values:
+
+.. code-block:: jinja
+
+ {% set fruits = ['apple', 'orange', 'citrus'] %}
+
+ {% for i in 0..10 %}
+ {{ cycle(fruits, i) }}
+ {% endfor %}
View
12 doc/functions/index.rst
@@ -0,0 +1,12 @@
+Functions
+=========
+
+.. toctree::
+ :maxdepth: 1
+
+ range
+ cycle
+ constant
+ attribute
+ block
+ parent
View
20 doc/functions/parent.rst
@@ -0,0 +1,20 @@
+``parent``
+==========
+
+When a template uses inheritance, it's possible to render the contents of the
+parent block when overriding a block by using the ``parent`` function:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% block sidebar %}
+ <h3>Table Of Contents</h3>
+ ...
+ {{ parent() }}
+ {% endblock %}
+
+The ``parent()`` call will return the content of the ``sidebar`` block as
+defined in the ``base.html`` template.
+
+.. seealso:: :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>`
View
38 doc/functions/range.rst
@@ -0,0 +1,38 @@
+``range``
+=========
+
+Returns a list containing an arithmetic progression of integers:
+
+.. code-block:: jinja
+
+ {% for i in range(0, 3) %}
+ {{ i }},
+ {% endfor %}
+
+ {# returns 0, 1, 2, 3 #}
+
+When step is given (as the third parameter), it specifies the increment (or
+decrement):
+
+.. code-block:: jinja
+
+ {% for i in range(0, 6, 2) %}
+ {{ i }},
+ {% endfor %}
+
+ {# returns 0, 2, 4, 6 #}
+
+The Twig built-in ``..`` operator is just syntactic sugar for the ``range``
+function (with a step of 1):
+
+.. code-block:: jinja
+
+ {% for i in 0..3 %}
+ {{ i }},
+ {% endfor %}
+
+.. tip::
+
+ The ``range`` function works as the native PHP `range`_ function.
+
+.. _`range`: http://php.net/range
View
4 doc/index.rst
@@ -11,3 +11,7 @@ Twig
extensions
hacking
recipes
+ tags/index
+ filters/index
+ functions/index
+ tests/index
View
43 doc/tags/autoescape.rst
@@ -0,0 +1,43 @@
+``autoescape``
+==============
+
+Whether automatic escaping is enabled or not, you can mark a section of a
+template to be escaped or not by using the ``autoescape`` tag:
+
+.. code-block:: jinja
+
+ {% autoescape true %}
+ Everything will be automatically escaped in this block
+ {% endautoescape %}
+
+ {% autoescape false %}
+ Everything will be outputed as is in this block
+ {% endautoescape %}
+
+ {% autoescape true js %}
+ Everything will be automatically escaped in this block
+ using the js escaping strategy
+ {% endautoescape %}
+
+When automatic escaping is enabled everything is escaped by default except for
+values explicitly marked as safe. Those can be marked in the template by using
+the :doc:`raw<../filters/raw>` filter:
+
+.. code-block:: jinja
+
+ {% autoescape true %}
+ {{ safe_value|raw }}
+ {% endautoescape %}
+
+Functions returning template data (like :doc:`macros<macro>` and
+:doc:`parent<../functions/parent>`) always return safe markup.
+
+.. note::
+
+ Twig is smart enough to not escape an already escaped value by the
+ :doc:`escape<../filters/escape>` filter.
+
+.. note::
+
+ The chapter :doc:`Twig for Developers<../api>` gives more information
+ about when and how automatic escaping is applied.
View
11 doc/tags/block.rst
@@ -0,0 +1,11 @@
+``block``
+=========
+
+Blocks are used for inheritance and act as placeholders and replacements at
+the same time. They are documented in detail in the documentation for the
+:doc:`extends<../tags/extends>` tag.
+
+Block names should consist of alphanumeric characters, and underscores. Dashes
+are not permitted.
+
+.. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`use<../tags/extends>`
View
188 doc/tags/extends.rst
@@ -0,0 +1,188 @@
+``extends``
+===========
+
+The ``extends`` tag can be used to extend a template from another one.
+
+.. note::
+
+ Like PHP, Twig does not support multiple inheritance. So you can only have
+ one extends tag called per rendering. However, Twig supports horizontal
+ :doc:`reuse<use>`.
+
+Let's define a base template, ``base.html``, which defines a simple HTML
+skeleton document:
+
+.. code-block:: html+jinja
+
+ <!DOCTYPE html>
+ <html>
+ <head>
+ {% block head %}
+ <link rel="stylesheet" href="style.css" />
+ <title>{% block title %}{% endblock %} - My Webpage</title>
+ {% endblock %}
+ </head>
+ <body>
+ <div id="content">{% block content %}{% endblock %}</div>
+ <div id="footer">
+ {% block footer %}
+ &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
+ {% endblock %}
+ </div>
+ </body>
+ </html>
+
+In this example, the :doc:`{% block %}<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:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% block title %}Index{% endblock %}
+ {% block head %}
+ {{ parent() }}
+ <style type="text/css">
+ .important { color: #336699; }
+ </style>
+ {% endblock %}
+ {% block content %}
+ <h1>Index</h1>
+ <p class="important">
+ Welcome on my awesome 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 extends tag should be the
+first tag in the template.
+
+Note that since the child template doesn't define the ``footer`` block, the
+value from the parent template is used instead.
+
+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.
+
+If you want to print a block multiple times you can however use the
+``block`` function:
+
+.. code-block:: jinja
+
+ <title>{% block title %}{% endblock %}</title>
+ <h1>{{ block('title') }}</h1>
+ {% block body %}{% endblock %}
+
+Parent Blocks
+-------------
+
+It's possible to render the contents of the parent block by using the
+:doc:`parent<../functions/parent>` function. This gives back the results of
+the parent block:
+
+.. code-block:: jinja
+
+ {% block sidebar %}
+ <h3>Table Of Contents</h3>
+ ...
+ {{ parent() }}
+ {% endblock %}
+
+Named Block End-Tags
+--------------------
+
+Twig allows you to put the name of the block after the end tag for better
+readability:
+
+.. code-block:: jinja
+
+ {% block sidebar %}
+ {% block inner_sidebar %}
+ ...
+ {% endblock inner_sidebar %}
+ {% endblock sidebar %}
+
+Of course, the name after the ``endblock`` word must match the block name.
+
+Block Nesting and Scope
+-----------------------
+
+Blocks can be nested for more complex layouts. Per default, blocks have access
+to variables from outer scopes:
+
+.. code-block:: jinja
+
+ {% for item in seq %}
+ <li>{% block loop_item %}{{ item }}{% endblock %}</li>
+ {% endfor %}
+
+Block Shortcuts
+---------------
+
+For blocks with few content, it's possible to use a shortcut syntax. The
+following constructs do the same:
+
+.. code-block:: jinja
+
+ {% block title %}
+ {{ page_title|title }}
+ {% endblock %}
+
+.. code-block:: jinja
+
+ {% block title page_title|title %}
+
+Dynamic Inheritance
+-------------------
+
+Twig supports dynamic inheritance by using a variable as the base template:
+
+.. code-block:: jinja
+
+ {% extends some_var %}
+
+If the variable evaluates to a ``Twig_Template`` object, Twig will use it as
+the parent template::
+
+ // {% extends layout %}
+
+ $layout = $twig->loadTemplate('some_layout_template.twig');
+
+ $twig->display('template.twig', array('layout' => $layout));
+
+.. versionadded:: 1.2
+ The possibility to pass an array of templates has been added in Twig 1.2.
+
+You can also provide a list of templates that are checked for existence. The
+first template that exists will be used as a parent:
+
+.. code-block:: jinja
+
+ {% extends ['layout.html', 'base_layout.html'] %}
+
+Conditional Inheritance
+-----------------------
+
+As the template name for the parent can be any valid Twig expression, it's
+possible to make the inheritance mechanism conditional:
+
+.. code-block:: jinja
+
+ {% extends standalone ? "minimum.html" : "base.html" %}
+
+In this example, the template will extend the "minimum.html" layout template
+if the ``standalone`` variable evaluates to ``true``, and "base.html"
+otherwise.
+
+.. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`
View
21 doc/tags/filter.rst
@@ -0,0 +1,21 @@
+``filter``
+==========
+
+Filter sections allow you to apply regular Twig filters on a block of template
+data. Just wrap the code in the special ``filter`` section:
+
+.. code-block:: jinja
+
+ {% filter upper %}
+ This text becomes uppercase
+ {% endfilter %}
+
+You can also chain filters:
+
+.. code-block:: jinja
+
+ {% filter lower|escape %}
+ <strong>SOME TEXT</strong>
+ {% endfilter %}
+
+ {# outputs "&lt;strong&gt;some text&lt;/strong&gt;" #}
View
126 doc/tags/for.rst
@@ -0,0 +1,126 @@
+``for``
+=======
+
+Loop over each item in a sequence. For example, to display a list of users
+provided in a variable called ``users``:
+
+.. code-block:: jinja
+
+ <h1>Members</h1>
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+
+.. note::
+
+ A sequence can be either an array or an object implementing the
+ ``Traversable`` interface.
+
+If you do need to iterate over a sequence of numbers, you can use the ``..``
+operator:
+
+.. code-block:: jinja
+
+ {% for i in 0..10 %}
+ * {{ i }}
+ {% endfor %}
+
+The above snippet of code would print all numbers from 0 to 10.
+
+It can be also useful with letters:
+
+.. code-block:: jinja
+
+ {% for letter in 'a'..'z' %}
+ * {{ letter }}
+ {% endfor %}
+
+The ``..`` operator can take any expression at both sides:
+
+.. code-block:: jinja
+
+ {% for letter in 'a'|upper..'z'|upper %}
+ * {{ letter }}
+ {% endfor %}
+
+.. tip:
+
+ If you need a step different from 1, you can use the ``range`` function
+ instead.
+
+Inside of a ``for`` loop block you can access some special variables:
+
+===================== =============================================================
+Variable Description
+===================== =============================================================
+``loop.index`` The current iteration of the loop. (1 indexed)
+``loop.index0`` The current iteration of the loop. (0 indexed)
+``loop.revindex`` The number of iterations from the end of the loop (1 indexed)
+``loop.revindex0`` The number of iterations from the end of the loop (0 indexed)
+``loop.first`` True if first iteration
+``loop.last`` True if last iteration
+``loop.length`` The number of items in the sequence
+``loop.parent`` The parent context
+===================== =============================================================
+
+.. note::
+
+ The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and
+ ``loop.last`` variables are only available for PHP arrays, or objects that
+ implement the ``Countable`` interface.
+
+.. versionadded:: 1.2
+ The ``if`` modifier support has been added in Twig 1.2.
+
+Unlike in PHP, it's not possible to ``break`` or ``continue`` in a loop. You
+can however filter the sequence during iteration which allows you to skip
+items. The following example skips all the users which are not active:
+
+.. code-block:: jinja
+
+ <ul>
+ {% for user in users if user.active %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+
+The advantage is that the special loop variable will count correctly thus not
+counting the users not iterated over.
+
+If no iteration took place because the sequence was empty, you can render a
+replacement block by using ``else``:
+
+.. code-block:: jinja
+
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% else %}
+ <li><em>no user found</em></li>
+ {% endfor %}
+ </ul>
+
+By default, a loop iterates over the values of the sequence. You can iterate
+on keys by using the ``keys`` filter:
+
+.. code-block:: jinja
+
+ <h1>Members</h1>
+ <ul>
+ {% for key in users|keys %}
+ <li>{{ key }}</li>
+ {% endfor %}
+ </ul>
+
+You can also access both keys and values:
+
+.. code-block:: jinja
+
+ <h1>Members</h1>
+ <ul>
+ {% for key, user in users %}
+ <li>{{ key }}: {{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
View
8 doc/tags/from.rst
@@ -0,0 +1,8 @@
+``from``
+========
+
+The ``from`` tags import :doc:`macro<../tags/macro>` names into the current
+namespace. The tag is documented in detail in the documentation for the
+:doc:`import<../tags/import>` tag.
+
+.. seealso:: :doc:`macro<../tags/macro>`, :doc:`import<../tags/import>`
View
33 doc/tags/if.rst
@@ -0,0 +1,33 @@
+``if``
+======
+
+The ``if`` statement in Twig is comparable with the if statements of PHP. In
+the simplest form you can use it to test if a variable is not empty:
+
+.. code-block:: jinja
+
+ {% if users %}
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+.. note::
+
+ If you want to test if the variable is defined, use ``if users is
+ defined`` instead.
+
+For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can use
+more complex ``expressions`` there too:
+
+.. code-block:: jinja
+
+ {% if kenny.sick %}
+ Kenny is sick.
+ {% elseif kenny.dead %}
+ You killed Kenny! You bastard!!!
+ {% else %}
+ Kenny looks okay --- so far
+ {% endif %}
View
79 doc/tags/import.rst
@@ -0,0 +1,79 @@
+``import``
+==========
+
+Twig supports putting often used code into :doc:`macros<../tags/macro>`. These
+macros can go into different templates and get imported from there.
+
+There are two ways to import templates. You can import the complete template
+into a variable or request specific macros from it.
+
+Imagine we have a helper module that renders forms (called ``forms.html``):
+
+.. code-block:: jinja
+
+ {% macro input(name, value, type, size) %}
+ <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
+ {% endmacro %}
+
+ {% macro textarea(name, value, rows) %}
+ <textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
+ {% endmacro %}
+
+The easiest and most flexible is importing the whole module into a variable.
+That way you can access the attributes:
+
+.. code-block:: jinja
+
+ {% import 'forms.html' as forms %}
+
+ <dl>
+ <dt>Username</dt>
+ <dd>{{ forms.input('username') }}</dd>
+ <dt>Password</dt>
+ <dd>{{ forms.input('password', none, 'password') }}</dd>
+ </dl>
+ <p>{{ forms.textarea('comment') }}</p>
+
+Alternatively you can import names from the template into the current
+namespace:
+
+.. code-block:: jinja
+
+ {% from 'forms.html' import input as input_field, textarea %}
+
+ <dl>
+ <dt>Username</dt>
+ <dd>{{ input_field('username') }}</dd>
+ <dt>Password</dt>
+ <dd>{{ input_field('password', type='password') }}</dd>
+ </dl>
+ <p>{{ textarea('comment') }}</p>
+
+Importing is not needed if the macros and the template are defined in the same
+file; use the special ``_self`` variable instead:
+
+.. code-block:: jinja
+
+ {# index.html template #}
+
+ {% macro textarea(name, value, rows) %}
+ <textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
+ {% endmacro %}
+
+ <p>{{ _self.textarea('comment') }}</p>
+
+But you can still create an alias by importing from the ``_self`` variable:
+
+.. code-block:: jinja
+
+ {# index.html template #}
+
+ {% macro textarea(name, value, rows) %}
+ <textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
+ {% endmacro %}
+
+ {% import _self as forms %}
+
+ <p>{{ forms.textarea('comment') }}</p>
+
+.. seealso:: :doc:`macro<../tags/macro>`, :doc:`from<../tags/from>`
View
83 doc/tags/include.rst
@@ -0,0 +1,83 @@
+``include``
+===========
+
+The ``include`` statement includes a template and return the rendered content
+of that file into the current namespace:
+
+.. code-block:: jinja
+
+ {% include 'header.html' %}
+ Body
+ {% include 'footer.html' %}
+
+Included templates have access to the variables of the active context.
+
+You can add additional variables by passing them after the ``with`` keyword:
+
+.. code-block:: jinja
+
+ {# the foo template will have access to the variables from the current context and the foo one #}
+ {% include 'foo' with {'foo': 'bar'} %}
+
+ {% set vars = {'foo': 'bar'} %}
+ {% include 'foo' with vars %}
+
+You can disable access to the context by appending the ``only`` keyword:
+
+.. code-block:: jinja
+
+ {# only the foo variable will be accessible #}
+ {% include 'foo' with {'foo': 'bar'} only %}
+
+.. code-block:: jinja
+
+ {# no variable will be accessible #}
+ {% include 'foo' only %}
+
+.. tip::
+
+ When including a template created by an end user, you should consider
+ sandboxing it. More information in the :doc:`Twig for Developers<../api>`
+ chapter.
+
+The template name can be any valid Twig expression:
+
+.. code-block:: jinja
+
+ {% include some_var %}
+ {% include ajax ? 'ajax.html' : 'not_ajax.html' %}
+
+And if the expression evaluates to a ``Twig_Template`` object, Twig will use it
+directly::
+
+ // {% include template %}
+
+ $template = $twig->loadTemplate('some_template.twig');
+
+ $twig->loadTemplate('template.twig')->display(array('template' => $template));
+
+.. versionadded:: 1.2
+ The ``ignore missing`` feature has been added in Twig 1.2.
+
+You can mark an include with ``ignore missing`` in which case Twig will ignore
+the statement if the template to be ignored does not exist. It has to be
+placed just after the template name. Here some valid examples:
+
+.. code-block:: jinja
+
+ {% include "sidebar.html" ignore missing %}
+ {% include "sidebar.html" ignore missing with {'foo': 'bar} %}
+ {% include "sidebar.html" ignore missing only %}
+
+.. versionadded:: 1.2
+ The possibility to pass an array of templates has been added in Twig 1.2.
+
+You can also provide a list of templates that are checked for existence before
+inclusion. The first template that exists will be included:
+
+.. code-block:: jinja
+
+ {% include ['page_detailed.html', 'page.html'] %}
+
+If ``ignore missing`` is given, it will fall back to rendering nothing if none
+of the templates exist, otherwise it will throw an exception.
View
20 doc/tags/index.rst
@@ -0,0 +1,20 @@
+Tags
+====
+
+.. toctree::
+ :maxdepth: 1
+
+ for
+ if
+ macro
+ filter
+ set
+ extends
+ block
+ include
+ import
+ from
+ use
+ spaceless
+ autoescape
+ raw
View
91 doc/tags/macro.rst
@@ -0,0 +1,91 @@
+``macro``
+=========
+
+Macros are comparable with functions in regular programming languages. They
+are useful to put often used HTML idioms into reusable elements to not repeat
+yourself.
+
+Here is a small example of a macro that renders a form element:
+
+.. code-block:: jinja
+
+ {% macro input(name, value, type, size) %}
+ <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
+ {% endmacro %}
+
+Macros differs from native PHP functions in a few ways:
+
+* Default argument values are defined by using the ``default`` filter in the
+ macro body;
+
+* Arguments of a macro are always optional.
+
+But as PHP functions, macros don't have access to the current template
+variables.
+
+.. tip::
+
+ You can pass the whole context as an argument by using the special
+ ``_context`` variable.
+
+Macros can be defined in any template, and need to be "imported" before being
+used (see the documentation for the :doc:`import<../tags/import>` tag for more
+information):
+
+.. code-block:: jinja
+
+ {% import "forms.html" as forms %}
+
+The above ``import`` call imports the "forms.html" file (which can contain only
+macros, or a template and some macros), and import the functions as items of
+the ``forms`` variable.
+
+The macro can then be called at will:
+
+.. code-block:: jinja
+
+ <p>{{ forms.input('username') }}</p>
+ <p>{{ forms.input('password', none, 'password') }}</p>
+
+If macros are defined and used in the same template, you can use the
+special ``_self`` variable, without importing them:
+
+.. code-block:: jinja
+
+ <p>{{ _self.input('username') }}</p>
+
+When you want to use a macro in another one from the same file, use the ``_self``
+variable:
+
+.. code-block:: jinja
+
+ {% macro input(name, value, type, size) %}
+ <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
+ {% endmacro %}
+
+ {% macro wrapped_input(name, value, type, size) %}
+ <div class="field">
+ {{ _self.input(name, value, type, size) }}
+ </div>
+ {% endmacro %}
+
+When the macro is defined in another file, you need to import it:
+
+.. code-block:: jinja
+
+ {# forms.html #}
+
+ {% macro input(name, value, type, size) %}
+ <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
+ {% endmacro %}
+
+ {# shortcuts.html #}
+
+ {% macro wrapped_input(name, value, type, size) %}
+ {% import "forms.html" as forms %}
+ <div class="field">
+ {{ forms.input(name, value, type, size) }}
+ </div>
+ {% endmacro %}
+
+.. seealso:: :doc:`from<../tags/from>`, :doc:`import<../tags/import>`
View
16 doc/tags/raw.rst
@@ -0,0 +1,16 @@
+``raw``
+=======
+
+The ``raw`` tag marks sections as being raw text that should not be parsed.
+For example to put Twig syntax as example into a template you can use this
+snippet:
+
+.. code-block:: jinja
+
+ {% raw %}
+ <ul>
+ {% for item in seq %}
+ <li>{{ item }}</li>
+ {% endfor %}
+ </ul>
+ {% endraw %}
View
32 doc/tags/set.rst
@@ -0,0 +1,32 @@
+``set``
+=======
+
+Inside code blocks you can also assign values to variables. Assignments use
+the ``set`` tag and can have multiple targets:
+
+.. code-block:: jinja
+
+ {% set foo = 'foo' %}
+
+ {% set foo = [1, 2] %}
+
+ {% set foo = {'foo': 'bar'} %}
+
+ {% set foo = 'foo' ~ 'bar' %}
+
+ {% set foo, bar = 'foo', 'bar' %}
+
+The ``set`` tag can also be used to 'capture' chunks of text:
+
+.. code-block:: jinja
+
+ {% set foo %}
+ <div id="pagination">
+ ...
+ </div>
+ {% endset %}
+
+.. caution::
+
+ If you enable automatic output escaping, Twig will only consider the
+ content to be safe when capturing chunks of text.
View
14 doc/tags/spaceless.rst
@@ -0,0 +1,14 @@
+``spaceless``
+=============
+
+Use the ``spaceless`` tag to remove whitespace *between HTML tags*:
+
+.. code-block:: jinja
+
+ {% spaceless %}
+ <div>
+ <strong>foo</strong>
+ </div>
+ {% endspaceless %}
+
+ {# output will be <div><strong>foo</strong></div> #}
View
123 doc/tags/use.rst
@@ -0,0 +1,123 @@
+``use``
+=======
+
+.. versionadded:: 1.1
+ Horizontal reuse was added in Twig 1.1.
+
+.. note::
+
+ Horizontal reuse is an advanced Twig feature that is hardly ever needed in
+ regular templates. It is mainly used by projects that need to make
+ template blocks reusable without using inheritance.
+
+Template inheritance is one of the most powerful Twig's feature but it is
+limited to single inheritance; a template can only extend one other template.
+This limitation makes template inheritance simple to understand and easy to
+debug:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+Horizontal reuse is a way to achieve the same goal as multiple inheritance,
+but without the associated complexity:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" %}
+
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+The ``use`` statement tells Twig to import the blocks defined in
+```blocks.html`` into the current template (it's like macros, but for blocks):
+
+.. code-block:: jinja
+
+ # blocks.html
+ {% block sidebar %}{% endblock %}
+
+In this example, the ``use`` statement imports the ``sidebar`` block into the
+main template. The code is mostly equivalent to the following one (the
+imported blocks are not outputted automatically):
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% block sidebar %}{% endblock %}
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+.. note::
+
+ The ``use`` tag only imports a template if it does not extend another
+ template, if it does not define macros, and if the body is empty. But it
+ can *use* other templates.
+
+.. note::
+
+ Because ``use`` statements are resolved independently of the context
+ passed to the template, the template reference cannot be an expression.
+
+The main template can also override any imported block. If the template
+already defines the ``sidebar`` block, then the one defined in ``blocks.html``
+is ignored. To avoid name conflicts, you can rename imported blocks:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" with sidebar as base_sidebar %}
+
+ {% block sidebar %}{% endblock %}
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+.. versionadded:: 1.3
+ The ``parent()`` support was added in Twig 1.3.
+
+The ``parent()`` function automatically determines the correct inheritance
+tree, so it can be used when overriding a block defined in an imported
+template:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" %}
+
+ {% block sidebar %}
+ {{ parent() }}
+ {% endblock %}
+
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+In this example, ``parent()`` will correctly call the ``sidebar`` block from
+the ``blocks.html`` template.
+
+.. tip::
+
+ In Twig 1.2, renaming allows you to simulate inheritance by calling the
+ "parent" block:
+
+ .. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" with sidebar as parent_sidebar %}
+
+ {% block sidebar %}
+ {{ block('parent_sidebar') }}
+ {% endblock %}
+
+.. note::
+
+ You can use as many ``use`` statements as you want in any given template.
+ If two imported templates define the same block, the latest one wins.
View
1,603 doc/templates.rst
@@ -12,29 +12,29 @@ XML, CSV, LaTeX, etc.). It doesn't have a specific extension, ``.html`` or
``.xml`` are just fine.
A template contains **variables** or **expressions**, which get replaced with
-values when the template is evaluated, and tags, which control the logic of
-the template.
+values when the template is evaluated, and **tags**, which control the logic
+of the template.
Below is a minimal template that illustrates a few basics. We will cover the
-details later in that document:
-
-.. code-block:: jinja
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
- <html lang="en">
- <head>
- <title>My Webpage</title>
- </head>
- <body>
- <ul id="navigation">
- {% for item in navigation %}
- <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
- {% endfor %}
- </ul>
-
- <h1>My Webpage</h1>
- {{ a_variable }}
- </body>
+details later on:
+
+.. code-block:: html+jinja
+
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>My Webpage</title>
+ </head>
+ <body>
+ <ul id="navigation">
+ {% for item in navigation %}
+ <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
+ {% endfor %}
+ </ul>
+
+ <h1>My Webpage</h1>
+ {{ a_variable }}
+ </body>
</html>
There are two kinds of delimiters: ``{% ... %}`` and ``{{ ... }}``. The first
@@ -59,12 +59,12 @@ Variables
The application passes variables to the templates you can mess around in the
template. Variables may have attributes or elements on them you can access
-too. How a variable looks like, heavily depends on the application providing
+too. How a variable looks like heavily depends on the application providing
those.
-You can use a dot (``.``) to access attributes of a variable, alternative the
-so-called "subscript" syntax (``[]``) can be used. The following lines do the
-same:
+You can use a dot (``.``) to access attributes of a variable (methods or
+properties of a PHP object, or items of a PHP array), or the so-called
+"subscript" syntax (``[]``):
.. code-block:: jinja
@@ -77,46 +77,52 @@ same:
variable but the print statement. If you access variables inside tags
don't put the braces around.
-If a variable or attribute does not exist you will get back a ``null`` value
-(which can be tested with the ``none`` expression).
+If a variable or attribute does not exist you will get back a ``null`` value.
.. sidebar:: Implementation
- For convenience sake ``foo.bar`` does the following things on the PHP
- layer:
-
- * check if ``foo`` is an array and ``bar`` a valid element;
- * if not, and if ``foo`` is an object, check that ``bar`` is a valid property;
- * if not, and if ``foo`` is an object, check that ``bar`` is a valid method
- (even if ``bar`` is the constructor - use ``__construct()`` instead);
- * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method;
- * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method;
- * if not, return a ``null`` value.
-
- ``foo['bar']`` on the other hand works mostly the same with the a small
- difference in the order:
+ For convenience sake ``foo.bar`` does the following things on the PHP
+ layer:
- * check if ``foo`` is an array and ``bar`` a valid element;
- * if not, return a ``null`` value.
+ * check if ``foo`` is an array and ``bar`` a valid element;
+ * if not, and if ``foo`` is an object, check that ``bar`` is a valid property;
+ * if not, and if ``foo`` is an object, check that ``bar`` is a valid method
+ (even if ``bar`` is the constructor - use ``__construct()`` instead);
+ * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method;
+ * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method;
+ * if not, return a ``null`` value.
- Using the alternative syntax is also useful to dynamically get attributes
- from arrays:
+ ``foo['bar']`` on the other hand only works with PHP arrays:
- .. code-block:: jinja
-
- foo[bar]
+ * check if ``foo`` is an array and ``bar`` a valid element;
+ * if not, return a ``null`` value.
.. note::
If you want to get a dynamic attribute on a variable, use the
- ``attribute`` function instead.
+ :doc:`attribute<functions/attribute>` function instead.
+
+Global Variables
+~~~~~~~~~~~~~~~~
-Twig always references the following variables:
+The following variables are always available in templates:
* ``_self``: references the current template;
* ``_context``: references the current context;
* ``_charset``: references the current charset.
+Setting Variables
+~~~~~~~~~~~~~~~~~
+
+You can assign values to variables inside code blocks. Assignments use the
+:doc:`set<tags/set>` tag:
+
+.. code-block:: jinja
+
+ {% set foo = 'foo' %}
+ {% set foo = [1, 2] %}
+ {% set foo = {'foo': 'bar'} %}
+
Filters
-------
@@ -125,103 +131,131 @@ variable by a pipe symbol (``|``) and may have optional arguments in
parentheses. Multiple filters can be chained. The output of one filter is
applied to the next.
-``{{ name|striptags|title }}`` for example will remove all HTML tags from the
-``name`` and title-cases it. Filters that accept arguments have parentheses
-around the arguments, like a function call. This example will join a list by
-commas: ``{{ list|join(', ') }}``.
+The following example removes all HTML tags from the ``name`` and title-cases
+it:
-The built-in filters section below describes all the built-in filters.
+.. code-block:: jinja
-Comments
---------
+ {{ name|striptags|title }}
-To comment-out part of a line in a template, use the comment syntax ``{# ...
-#}``. This is useful to comment out parts of the template for debugging or to
-add information for other template designers or yourself:
+Filters that accept arguments have parentheses around the arguments. This
+example will join a list by commas:
.. code-block:: jinja
- {# note: disabled template because we no longer use this
- {% for user in users %}
- ...
- {% endfor %}
- #}
+ {{ list|join(', ') }}
-Whitespace Control
-------------------
+To apply a filter on a section of code, wrap it with the
+:doc:`filter<tags/filter>` tag:
-.. versionadded:: 1.1
- Tag level whitespace control was added in Twig 1.1.
+.. code-block:: jinja
-The first newline after a template tag is removed automatically (like in PHP.)
-Whitespace is not further modified by the template engine, so each whitespace
-(spaces, tabs, newlines etc.) is returned unchanged.
+ {% filter upper %}
+ This text becomes uppercase
+ {% endfilter %}
+
+Go to the :doc:`filters<filters/index>` page to learn more about the built-in
+filters.
-Use the ``spaceless`` tag to remove whitespace between HTML tags:
+Functions
+---------
+
+Functions can be called to generate content. Functions are called by their
+name followed by parentheses (``()``) and may have arguments.
+
+For instance, the ``range`` function returns a list containing an arithmetic
+progression of integers:
.. code-block:: jinja
- {% spaceless %}
- <div>
- <strong>foo</strong>
- </div>
- {% endspaceless %}
+ {% for i in range(0, 3) %}
+ {{ i }},
+ {% endfor %}
- {# output will be <div><strong>foo</strong></div> #}
+Go to the :doc:`functions<functions/index>` page to learn more about the
+built-in functions.
-In addition to the spaceless tag you can also control whitespace on a per tag
-level. By using the whitespace control modifier on your tags you can trim
-leading and or trailing whitespace from any tag type:
+Control Structure
+-----------------
-.. code-block:: jinja
+A control structure refers to all those things that control the flow of a
+program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as
+well as things like blocks. Control structures appear inside ``{% ... %}``
+blocks.
- {% set value = 'no spaces' %}
- {#- No leading/trailing whitespace -#}
- {%- if true -%}
- {{- value -}}
- {%- endif -%}
+For example, to display a list of users provided in a variable called
+``users``, use the :doc:`for<tags/for>` tag:
- {# output 'no spaces' #}
+.. code-block:: jinja
-The above sample shows the default whitespace control modifier, and how you can
-use it to remove whitespace around tags. Trimming space will consume all whitespace
-for that side of the tag. It is possible to use whitespace trimming on one side
-of a tag:
+ <h1>Members</h1>
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+
+The :doc:`if<tags/if>` tag can be used to test an expression:
.. code-block:: jinja
- {% set value = 'no spaces' %}
- <li> {{- value }} </li>
+ {% if users|length > 0 %}
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
- {# outputs '<li>no spaces </li>' #}
+Go to the :doc:`tags<tags/index>` page to learn more about the built-in tags.
-Escaping
+Comments
--------
-It is sometimes desirable or even necessary to have Twig ignore parts it would
-otherwise handle as variables or blocks. For example if the default syntax is
-used and you want to use ``{{`` as raw string in the template and not start a
-variable you have to use a trick.
+To comment-out part of a line in a template, use the comment syntax ``{# ...
+#}``. This is useful for debugging or to add information for other template
+designers or yourself:
-The easiest way is to output the variable delimiter (``{{``) by using a variable
-expression:
+.. code-block:: jinja
+
+ {# note: disabled template because we no longer use this
+ {% for user in users %}
+ ...
+ {% endfor %}
+ #}
+
+Including other Templates
+-------------------------
+
+The :doc:`include<tags/include>` tag is useful to include a template and
+return the rendered content of that template into the current one:
.. code-block:: jinja
- {{ '{{' }}
+ {% include 'sidebar.html' %}
+
+Per default included templates are passed the current context.
+
+The context that is passed to the included template includes variables defined
+in the template:
+
+.. code-block:: jinja
+
+ {% for box in boxes %}
+ {% include "render_box.html" %}
+ {% endfor %}
+
+The included template ``render_box.html`` is able to access ``box``.
-For bigger sections it makes sense to mark a block ``raw``. For example to put
-Twig syntax as example into a template you can use this snippet:
+The filename of the template depends on the template loader. For instance, the
+``Twig_Loader_Filesystem`` allows you to access other templates by giving the
+filename. You can access templates in subdirectories with a slash:
.. code-block:: jinja
- {% raw %}
- <ul>
- {% for item in seq %}
- <li>{{ item }}</li>
- {% endfor %}
- </ul>
- {% endraw %}
+ {% include "sections/articles/sidebar.html" %}
+
+This behavior depends on the application embedding Twig.
Template Inheritance
--------------------
@@ -234,39 +268,33 @@ 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:
-
-.. code-block:: jinja
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
- <html lang="en">
- <head>
- {% block head %}
- <link rel="stylesheet" href="style.css" />
- <title>{% block title %}{% endblock %} - My Webpage</title>
- {% endblock %}
- </head>
- <body>
- <div id="content">{% block content %}{% endblock %}</div>
- <div id="footer">
- {% block footer %}
- &copy; Copyright 2009 by <a href="http://domain.invalid/">you</a>.
- {% endblock %}
- </div>
- </body>
+Let's define a base template, ``base.html``, which defines a simple HTML
+skeleton document that you might use for a simple two-column page:
+
+.. code-block:: html+jinja
+
+ <!DOCTYPE html>
+ <html>
+ <head>
+ {% block head %}
+ <link rel="stylesheet" href="style.css" />
+ <title>{% block title %}{% endblock %} - My Webpage</title>
+ {% endblock %}
+ </head>
+ <body>
+ <div id="content">{% block content %}{% endblock %}</div>
+ <div id="footer">
+ {% block footer %}
+ &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
+ {% endblock %}
+ </div>
+ </body>
</html>
-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
-~~~~~~~~~~~~~~
+In this example, the :doc:`{% block %}<tags/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.
A child template might look like this:
@@ -276,170 +304,43 @@ A child template might look like this:
{% block title %}Index{% endblock %}
{% block head %}
- {{ parent() }}
- <style type="text/css">
- .important { color: #336699; }
- </style>
+ {{ parent() }}
+ <style type="text/css">
+ .important { color: #336699; }
+ </style>
{% endblock %}
{% block content %}
- <h1>Index</h1>
- <p class="important">
- Welcome on my awesome homepage.
- </p>
+ <h1>Index</h1>
+ <p class="important">
+ Welcome on my awesome 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 extends tag should be the
-first tag in the template.
-
-The filename of the template depends on the template loader. For example the
-``Twig_Loader_Filesystem`` allows you to access other templates by giving the
-filename. You can access templates in subdirectories with a slash:
-
-.. code-block:: jinja
-
- {% extends "layout/default.html" %}
-
-But this behavior can depend on the application embedding Twig. Note that
-since the child template doesn't define the ``footer`` block, the value from
-the parent template is used instead.
-
-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. Block names should
-consist of alphanumeric characters, and underscores. Dashes are not permitted.
-
-If you want to print a block multiple times you can however use the
-``block`` function:
-
-.. code-block:: jinja
-
- <title>{% block title %}{% endblock %}</title>
- <h1>{{ block('title') }}</h1>
- {% block body %}{% endblock %}
-
-Like PHP, Twig does not support multiple inheritance. So you can only have one
-extends tag called per rendering.
-
-Parent Blocks
-~~~~~~~~~~~~~
-
-It's possible to render the contents of the parent block by using the ``parent``
-function. This gives back the results of the parent block:
-
-.. code-block:: jinja
-
- {% block sidebar %}
- <h3>Table Of Contents</h3>
- ...
- {{ parent() }}
- {% endblock %}
+The :doc:`{% extends %}<tags/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
+extends tag should be the first tag in the template.
-Named Block End-Tags
-~~~~~~~~~~~~~~~~~~~~
+Note that since the child template doesn't define the ``footer`` block, the
+value from the parent template is used instead.
-Twig allows you to put the name of the block after the end tag for better
-readability:
+It's possible to render the contents of the parent block by using the
+:doc:`parent<functions/parent>` function. This gives back the results of the
+parent block:
.. code-block:: jinja
{% block sidebar %}
- {% block inner_sidebar %}
- ...
- {% endblock inner_sidebar %}
- {% endblock sidebar %}
-
-However the name after the ``endblock`` word must match the block name.
-
-Block Nesting and Scope
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Blocks can be nested for more complex layouts. Per default, blocks have access
-to variables from outer scopes:
-
-.. code-block:: jinja
-
- {% for item in seq %}
- <li>{% block loop_item %}{{ item }}{% endblock %}</li>
- {% endfor %}
-
-Block Shortcuts
-~~~~~~~~~~~~~~~
-
-For blocks with few content, it's possible to have a shortcut syntax. The
-following constructs do the same:
-
-.. code-block:: jinja
-
- {% block title %}
- {{ page_title|title }}
+ <h3>Table Of Contents</h3>
+ ...
+ {{ parent() }}
{% endblock %}
-.. code-block:: jinja
-
- {% block title page_title|title %}
-
-Dynamic Inheritance
-~~~~~~~~~~~~~~~~~~~
-
-Twig supports dynamic inheritance by using a variable as the base template:
-
-.. code-block:: jinja
-
- {% extends some_var %}
-
-If the variable evaluates to a ``Twig_Template`` object, Twig will use it as
-the parent template::
-
- // {% extends layout %}
-
- $layout = $twig->loadTemplate('some_layout_template.twig');
-
- $twig->display('template.twig', array('layout' => $layout));
-
-.. versionadded:: 1.2
- The possibility to pass an array of templates has been added in Twig 1.2.
-
-You can also provide a list of templates that are checked for existence. The
-first template that exists will be used as a parent:
-
-.. code-block:: jinja
-
- {% extends ['layout.html', 'base_layout.html'] %}
-
-Conditional Inheritance
-~~~~~~~~~~~~~~~~~~~~~~~
-
-As a matter of fact, the template name can be any valid expression. So, it's
-also possible to make the inheritance mechanism conditional:
-
-.. code-block:: jinja
-
- {% extends standalone ? "minimum.html" : "base.html" %}
-
-In this example, the template will extend the "minimum.html" layout template
-if the ``standalone`` variable evaluates to ``true``, and "base.html"
-otherwise.
-
-Import Context Behavior
------------------------
-
-Per default included templates are passed the current context.
-
-The context that is passed to the included template includes variables defined
-in the template:
-
-.. code-block:: jinja
-
- {% for box in boxes %}
- {% include "render_box.html" %}
- {% endfor %}
+.. tip::
-The included template ``render_box.html`` is able to access ``box``.
+ The documentation page for the :doc:`extends<tags/extends>` tag describes
+ more advanced features like block nesting, scope, dynamic inheritance, and
+ conditional inheritance.
HTML Escaping
-------------
@@ -461,558 +362,109 @@ Working with Manual Escaping
If manual escaping is enabled it's **your** responsibility to escape variables
if needed. What to escape? If you have a variable that *may* include any of
-the following chars (``>``, ``<``, ``&``, or ``"``) you **have to** escape it unless
-the variable contains well-formed and trusted HTML. Escaping works by piping
-the variable through the ``|e`` filter: ``{{ user.username|e }}``.
+the following chars (``>``, ``<``, ``&``, or ``"``) you **have to** escape it
+unless the variable contains well-formed and trusted HTML. Escaping works by
+piping the variable through the :doc:`escape<filters/escape>` or ``e`` filter:
+
+.. code-block:: jinja
+
+ {{ user.username|e }}
+ {{ user.username|e('js') }}
Working with Automatic Escaping
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Whether automatic escaping is enabled or not, you can mark a section of a
-template to be escaped or not by using the ``autoescape`` tag:
+template to be escaped or not by using the :doc:`autoescape<tags/autoescape>`
+tag:
.. code-block:: jinja
{% autoescape true %}
- Everything will be automatically escaped in this block
+ Everything will be automatically escaped in this block
{% endautoescape %}
- {% autoescape false %}
- Everything will be outputed as is in this block
- {% endautoescape %}
-
- {% autoescape true js %}
- Everything will be automatically escaped in this block
- using the js escaping strategy
- {% endautoescape %}
-
-When automatic escaping is enabled everything is escaped by default except for
-values explicitly marked as safe. Those can be marked in the template by using
-the ``|raw`` filter.
-
-Functions returning template data (like macros and ``parent``) always return
-safe markup.
+Escaping
+--------
-.. note::
+It is sometimes desirable or even necessary to have Twig ignore parts it would
+otherwise handle as variables or blocks. For example if the default syntax is
+used and you want to use ``{{`` as raw string in the template and not start a
+variable you have to use a trick.
- Twig is smart enough to not escape an already escaped value by the
- ``escape`` filter.
+The easiest way is to output the variable delimiter (``{{``) by using a variable
+expression:
-.. note::
+.. code-block:: jinja
- The chapter for developers give more information about when and how
- automatic escaping is applied.
+ {{ '{{' }}
-List of Control Structures
---------------------------
+For bigger sections it makes sense to mark a block :doc:`raw<tags/raw>`.
-A control structure refers to all those things that control the flow of a
-program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as well as
-things like blocks. Control structures appear inside ``{% ... %}`` blocks.
+Macros
+------
-For
-~~~
+Macros are comparable with functions in regular programming languages. They
+are useful to put often used HTML idioms into reusable elements to not repeat
+yourself.
-Loop over each item in a sequence. For example, to display a list of users
-provided in a variable called ``users``:
+A macro is defined via the :doc:`macro<tags/macro>` tag. Here is a small
+example of a macro that renders a form element:
.. code-block:: jinja
- <h1>Members</h1>
- <ul>
- {% for user in users %}
- <li>{{ user.username|e }}</li>
- {% endfor %}
- </ul>
-
-.. note::
-
- A sequence can be either an array or an object implementing the
- ``Traversable`` interface.
+ {% macro input(name, value, type, size) %}
+ <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
+ {% endmacro %}
-If you do need to iterate over a sequence of numbers, you can use the ``..``
-operator:
+Macros can be defined in any template, and need to be "imported" before being
+used via the :doc:`import<tags/import>` tag:
.. code-block:: jinja
- {% for i in 0..10 %}
- * {{ i }}
- {% endfor %}
-
-The above snippet of code would print all numbers from 0 to 10.
-
-It can be also useful with letters:
-
-.. code-block:: jinja
+ {% import "forms.html" as forms %}
- {% for letter in 'a'..'z' %}
- * {{ letter }}
- {% endfor %}
+ <p>{{ forms.input('username') }}</p>
-The ``..`` operator can take any expression at both sides:
+Alternatively you can import names from the template into the current
+namespace via the :doc:`from<tags/from>` tag:
.. code-block:: jinja
- {% for letter in 'a'|upper..'z'|upper %}
- * {{ letter }}
- {% endfor %}
-
-.. tip:
+ {% from 'forms.html' import input as input_field, textarea %}
- If you need a step different from 1, you can use the ``range`` function
- instead.
+ <dl>
+ <dt>Username</dt>
+ <dd>{{ input_field('username') }}</dd>
+ <dt>Password</dt>
+ <dd>{{ input_field('password', type='password') }}</dd>
+ </dl>
+ <p>{{ textarea('comment') }}</p>
-Inside of a ``for`` loop block you can access some special variables:
+Expressions
+-----------
-===================== =============================================================
-Variable Description
-===================== =============================================================
-``loop.index`` The current iteration of the loop. (1 indexed)
-``loop.index0`` The current iteration of the loop. (0 indexed)
-``loop.revindex`` The number of iterations from the end of the loop (1 indexed)
-``loop.revindex0`` The number of iterations from the end of the loop (0 indexed)
-``loop.first`` True if first iteration
-``loop.last`` True if last iteration
-``loop.length`` The number of items in the sequence
-``loop.parent`` The parent context
-===================== =============================================================
+Twig allows expressions everywhere. These work very similar to regular PHP and
+even if you're not working with PHP you should feel comfortable with it.
.. note::
- The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and
- ``loop.last`` variables are only available for PHP arrays, or objects that
- implement the ``Countable`` interface.
+ The operator precedence is as follows, with the lowest-precedence
+ operators listed first: ``or``, ``and``, ``==``, ``!=``, ``<``, ``>``,
+ ``>=``, ``<=``, ``in``, ``+``, ``-``, ``~``, ``*``, ``/``, ``%``, ``//``,
+ ``is``, ``..``, and ``**``.
-.. versionadded:: 1.2
- The ``if`` modifier support has been added in Twig 1.2.
+Literals
+~~~~~~~~
-Unlike in PHP, it's not possible to ``break`` or ``continue`` in a loop. You
-can however filter the sequence during iteration which allows you to skip
-items. The following example skips all the users which are not active:
+The simplest form of expressions are literals. Literals are representations
+for PHP types such as strings, numbers, and arrays. The following literals
+exist:
-.. code-block:: jinja
-
- <ul>
- {% for user in users if user.active %}
- <li>{{ user.username|e }}</li>
- {% endfor %}
- </ul>
-
-The advantage is that the special loop variable will count correctly thus not
-counting the users not iterated over.
-
-If no iteration took place because the sequence was empty, you can render a
-replacement block by using ``else``:
-
-.. code-block:: jinja
-
- <ul>
- {% for user in users %}
- <li>{{ user.username|e }}</li>
- {% else %}
- <li><em>no user found</em></li>
- {% endfor %}
- </ul>
-
-By default, a loop iterates over the values of the sequence. You can iterate
-on keys by using the ``keys`` filter:
-
-.. code-block:: jinja
-
- <h1>Members</h1>
- <ul>
- {% for key in users|keys %}
- <li>{{ key }}</li>
- {% endfor %}
- </ul>
-
-You can also access both keys and values:
-
-.. code-block:: jinja
-
- <h1>Members</h1>
- <ul>
- {% for key, user in users %}
- <li>{{ key }}: {{ user.username|e }}</li>
- {% endfor %}
- </ul>
-
-If
-~~
-
-The ``if`` statement in Twig is comparable with the if statements of PHP. In
-the simplest form you can use it to test if a variable is not empty:
-
-.. code-block:: jinja
-
- {% if users %}
- <ul>
- {% for user in users %}
- <li>{{ user.username|e }}</li>
- {% endfor %}
- </ul>
- {% endif %}
-
-.. note::
-
- If you want to test if the variable is defined, use ``if users is
- defined`` instead.
-
-For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can use
-more complex ``expressions`` there too:
-
-.. code-block:: jinja
-
- {% if kenny.sick %}
- Kenny is sick.
- {% elseif kenny.dead %}
- You killed Kenny! You bastard!!!
- {% else %}
- Kenny looks okay --- so far
- {% endif %}
-
-Macros
-~~~~~~
-
-Macros are comparable with functions in regular programming languages. They
-are useful to put often used HTML idioms into reusable elements to not repeat
-yourself.
-
-Here is a small example of a macro that renders a form element:
-
-.. code-block:: jinja
-
- {% macro input(name, value, type, size) %}
- <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
- {% endmacro %}
-
-Macros differs from native PHP functions in a few ways:
-
-* Default argument values are defined by using the ``default`` filter in the
- macro body;
-
-* Arguments of a macro are always optional.
-
-But as PHP functions, macros don't have access to the current template
-variables.