mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-21 07:37:43 +00:00
refactored documentation
This commit is contained in:
@@ -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' #}
|
||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
@@ -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>`
|
||||||
@@ -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
|
||||||
@@ -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 #}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
``json_encode``
|
||||||
|
===============
|
||||||
|
|
||||||
|
The ``json_encode`` filter returns the JSON representation of a string:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ data|json_encode() }}
|
||||||
@@ -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 %}
|
||||||
@@ -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 %}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
``lower``
|
||||||
|
=========
|
||||||
|
|
||||||
|
The ``lower`` filter converts a value to lowercase:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ 'WELCOME'|lower }}
|
||||||
|
|
||||||
|
{# outputs 'welcome' #}
|
||||||
@@ -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' } #}
|
||||||
@@ -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 %}
|
||||||
@@ -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>`
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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' #}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
``upper``
|
||||||
|
=========
|
||||||
|
|
||||||
|
The ``upper`` filter converts a value to uppercase:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ 'welcome'|upper }}
|
||||||
|
|
||||||
|
{# outputs 'WELCOME' #}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
``url_encode``
|
||||||
|
==============
|
||||||
|
|
||||||
|
The ``url_encode`` filter URL encodes a given string:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ data|url_encode() }}
|
||||||
@@ -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.
|
||||||
@@ -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>`
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
``constant``
|
||||||
|
============
|
||||||
|
|
||||||
|
``constant`` returns the constant value for a given string:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ some_date|date(constant('DATE_W3C')) }}
|
||||||
@@ -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 %}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
Functions
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
range
|
||||||
|
cycle
|
||||||
|
constant
|
||||||
|
attribute
|
||||||
|
block
|
||||||
|
parent
|
||||||
@@ -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>`
|
||||||
@@ -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
|
||||||
@@ -11,3 +11,7 @@ Twig
|
|||||||
extensions
|
extensions
|
||||||
hacking
|
hacking
|
||||||
recipes
|
recipes
|
||||||
|
tags/index
|
||||||
|
filters/index
|
||||||
|
functions/index
|
||||||
|
tests/index
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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>`
|
||||||
@@ -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 %}
|
||||||
|
© 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>`
|
||||||
@@ -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 "<strong>some text</strong>" #}
|
||||||
@@ -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>
|
||||||
@@ -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>`
|
||||||
@@ -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 %}
|
||||||
@@ -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>`
|
||||||
@@ -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.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
Tags
|
||||||
|
====
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
for
|
||||||
|
if
|
||||||
|
macro
|
||||||
|
filter
|
||||||
|
set
|
||||||
|
extends
|
||||||
|
block
|
||||||
|
include
|
||||||
|
import
|
||||||
|
from
|
||||||
|
use
|
||||||
|
spaceless
|
||||||
|
autoescape
|
||||||
|
raw
|
||||||
@@ -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>`
|
||||||
@@ -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 %}
|
||||||
@@ -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.
|
||||||
@@ -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> #}
|
||||||
@@ -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.
|
||||||
+274
-1273
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
|||||||
|
``constant``
|
||||||
|
============
|
||||||
|
|
||||||
|
``constant`` checks if a variable has the exact same value as a constant. You
|
||||||
|
can use either global constants or class constants:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% if post.status is constant('Post::PUBLISHED') %}
|
||||||
|
the status attribute is exactly the same as Post::PUBLISHED
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
``defined``
|
||||||
|
===========
|
||||||
|
|
||||||
|
``defined`` checks if a variable is defined in the current context. This is very
|
||||||
|
useful if you use the ``strict_variables`` option:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{# defined works with variable names #}
|
||||||
|
{% if foo is defined %}
|
||||||
|
...
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# and attributes on variables names #}
|
||||||
|
{% if foo.bar is defined %}
|
||||||
|
...
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
``divisibleby``
|
||||||
|
===============
|
||||||
|
|
||||||
|
``divisibleby`` checks if a variable is divisible by a number:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% if loop.index is divisibleby(3) %}
|
||||||
|
...
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
``empty``
|
||||||
|
=========
|
||||||
|
|
||||||
|
``empty`` checks if a variable is empty:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{# evaluates to true if the foo variable is null, false, or the empty string #}
|
||||||
|
{% if foo is empty %}
|
||||||
|
...
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
``even``
|
||||||
|
========
|
||||||
|
|
||||||
|
``even`` returns ``true`` if the given number is even:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ var is even }}
|
||||||
|
|
||||||
|
.. seealso:: :doc:`odd<../tests/odd>`
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Tests
|
||||||
|
=====
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
divisibleby
|
||||||
|
none
|
||||||
|
even
|
||||||
|
odd
|
||||||
|
sameas
|
||||||
|
constant
|
||||||
|
defined
|
||||||
|
empty
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
``none``
|
||||||
|
========
|
||||||
|
|
||||||
|
``none`` returns ``true`` if the variable is ``none``:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ var is none }}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
``odd``
|
||||||
|
=======
|
||||||
|
|
||||||
|
``odd`` returns ``true`` if the given number is odd:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ var is odd }}
|
||||||
|
|
||||||
|
.. seealso:: :doc:`even<../tests/even>`
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
``sameas``
|
||||||
|
==========
|
||||||
|
|
||||||
|
``sameas`` checks if a variable points to the same memory address than another
|
||||||
|
variable:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% if foo.attribute is sameas(false) %}
|
||||||
|
the foo attribute really is the ``false`` PHP value
|
||||||
|
{% endif %}
|
||||||
Reference in New Issue
Block a user