Control Methods

Boolean Logic

In Twig, it is not possible to combine expressions with standard programming synax like '||', '&&' and '!'.  Instead it is necessary to use 'and', 'or' and 'not':

{% if not var and ( foo == 5 or foo == 10 ) %} 

The following comparison operators are supported in any expression: ==!=<>>=, and <=.

Besides PHP classic comparison operators, Twig also supports a shortcut notation when you want to test a value in a range:

{% if 1 < foo < 4 %}foo is between 1 and 4{% endif %}

Other Operators

The following operators are very useful but don't fit into any of the other two categories:

  • in (new in Twig 0.9.5): Performs containment test. Returns true if the left operand is contained in the right. {{ 1 in [1, 2, 3] }} would for example return true. To perform a negative test, the whole expression should be prefixed with not ({{ not 1 in [1, 2, 3] }} would return false).

  • .. (new in Twig 0.9.5): Creates a sequence based on the operand before and after the operator (see the for tag for some usage examples).

  • |: Applies a filter.

  • ~: Converts all operands into strings and concatenates them. {{ "Hello " ~ name ~ "!" }} would return (assuming name is 'John')Hello John!.

  • .[]: Gets an attribute of an object.

  • ?:: Twig supports the PHP ternary operator:

    {{ foo ? 'yes' : 'no' }}

For

Loop over each item in a sequence. For example, to display a list of users provided in a variable called users:

<h1>Members</h1>
<ul>
  {% for user in users %}
    <li>{{ user.username|e }}</li>
  {% endfor %}
</ul>

A sequence can be either an array or an object implementing the Iterator interface.

If you do need to iterate over a sequence of numbers, you can use the .. operator (as of Twig 0.9.5):

{% 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:

{% for letter in 'a'..'z' %}
  * {{ letter }}
{% endfor %}

The .. operator can take any expression at both sides:

{% for letter in 'a'|upper..'z'|upper %}
  * {{ letter }}
{% endfor %}

If you need a step different from 1, you can use the range filter instead:

{% for i in 0|range(10, 2) %}
  * {{ i }}
{% endfor %}

Inside of a for loop block you can access some special variables (if you don't need them, you can add without loop at the end of the forstatement for a small speed boost):

VariableDescription
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

The loop.lengthloop.revindexloop.revindex0, and loop.last variables are only available for PHP arrays, or objects that implement the Countable interface (as of Twig 0.9.7).

Unlike in PHP it's not possible to break or continue in a loop.

If no iteration took place because the sequence was empty, you can render a replacement block by using else:

<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:

<h1>Members</h1>
<ul>
  {% for key in users|keys %}
    <li>{{ key }}</li>
  {% endfor %}
</ul>

You can also access both keys and values:

<h1>Members</h1>
<ul>
  {% for key, user in users %}
    <li>{{ key }}: {{ user.username|e }}</li>
  {% endfor %}
</ul>

On Twig before 0.9.3, you need to use the items filter to access both the keys and values ({% for key, value in users|items %}).

 

HiFi Results

Looping over HiFi results is extremely common, so it deserves it's own section.  It is simple using a for loop and hifi.get:

{% for post in hifi.get({'type':'post'}) %}
  {{ post.title }}
{% endfor %}

hifi.get always returns an array, so this is the best way to loop through the results of a HiFi query. The HiFi query can be as complex as desired. Here is one showing the latest news of a site:

{% for newsItem in hifi.get({'type':'post','parent':{'url':'/news'},'orderBy','-publishedAt','count',3}) %}
  <a href="{{ newsItem.url }}">{{ newsItem.title }}</a>
{% endfor %}

If/Else/ElseIf

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 defined, not empty or not false:

{% if users %}
  <ul>
    {% for user in users %}
      <li>{{ user.username|e }}</li>
    {% endfor %}
  </ul>
{% endif %}

For multiple branches elseif and else can be used like in PHP. You can use more complex expressions there too:

{% if kenny.sick %}
  Kenny is sick.
{% elseif kenny.dead %}
  You killed Kenny!
{% else %}
  Kenny looks okay --- so far
{% endif %}