Twig basics

Twig autoescape enabled

To escape a string means to reduce ambiguous characters in a string.

Twig autoescape is enabled by default. This means that every string printed from a Twig template (anything between {{ }}) gets escaped.

Printing a variable

To print a variable in a template, use {{ variable }}, eg. {{ foo }}

A dot (.) can be used to access attributes of a variable:

{{ }}

Twig will automatically check for the following options:

// Array key.
// Object property.
// Object method.
// Object get method convention.
// Object is method convention.
// Object dynamic object property is set and get property.


$awesome_array = array(
  'a_key' => 'a_value',
  'another_key' => array(
    'foo' => 'bar',


{{ awesome_array.a_key }} # returns 'a_value'
{{ }} # returns 'bar'

Twig filters

It's possible to let the variable go through a filter before printing it. This can be done using {{ variable|filter }}.

Twig filters

Here are some example of filters from the Twig engine.

  • |length, returns the number of items of a sequence or mapping, or the length of a string.
  • |lower, converts a value to lowercase.
  • |upper, converts a value to uppercase.

A complete list of default Twig filters can be found here.

Drupal filters

Drupal offers some additional filters.

Translation filters
  • t will run the variable through the Drupal t() function, which will return a translated string. An example:

  • passthrough

  • placeholder

To safely escape all of the Twig variables detected in a {% trans %} tag, the variables are sent with an @ prefix by default. To pass-through a variable (!) or use as a placeholder (%), the passthrough or placeholder filters are used.

  • passthrough gets no sanitization or formatting and should only be used for text that has already been prepared for HTML display.
  • placeholder gets escaped to HTML and formatted using drupal_placeholder(), which makes it display as emphasized text.

  • raw will show the raw data (meaning without any escaping).

Replace twig's escape filter with our own.
Implements safe joining.
Array filters
  • without creates a copy of the renderable array and removes child elements by key specified through filter's arguments. The copy can be printed without these elements. The original renderable array is still available and can be used to print child elements in their entirety in the twig template.
CSS class and ID filters.


The Twig i18n extension allows marking parts of a template as translatable. Let's start of with an easy example:

{% trans %} Hello world {% endtrans %}

It's possible to embed a variable in a translatable string, using the {{ variable }} syntax.

{% trans %} Hello {{ name }} {% endtrans %}

To apply a filter to a variable, used in a translatable block you first need to assign the result to a variable.

{% set name = name|capitalize %}

{% trans %}
  Hello {{ name }}!
{% endtrans %}

A translatable string can be pluralized. Implementing a {% plural ... %} switch makes this possible.

{% trans %}
  Hello star.
{% plural count %}
  Hello {{ count }} stars.
{% endtrans %}


{# Comments go inside these brackets. #}


An if function.

{% if site_slogan %}
  <div class="site-slogan">{{ site_slogan }}</div>
{% endif %}


A for function. The output for this is 0, 1, 2, 3.

The range function returns a list containing an arithmetic progression of integers.

{% for i in range(0, 3) %}
  {{ i }},
{% endfor %}

Another example, from the field--node--title.html.twig template:

{% for item in items %}
  {{ item.content }}
{% endfor %}

Inside of a for loop block you can access some special variables.

Variable Description
items.index The current iteration of the loop. (1 indexed)
items.index0 The current iteration of the loop. (0 indexed)
items.revindex The number of iterations from the end of the loop (1 indexed)
items.revindex0 The number of iterations from the end of the loop (0 indexed)
items.first True if first iteration
items.last True if last iteration
items.length The number of items in the sequence
items.parent The parent context

A replacement block can be rendered if no iteration took place (because the sequence was empty). This can be done by using else.

{% for user in users %}
  <li>{{ user.username|e }}</li>
{% else %}
  <li><em>no user found</em></li>
{% endfor %}

Create a Twig variable

Sometimes it might be useful to define variables in a template file. {% set foo="bar" %} declares a variable foo and assigns the value bar to it. Later in the template, the variable can be printed out using {{ foo }}.


{% set foo="bar" %}

# Other code here

Hi, here's my variable: {{ foo }}

The variable can be a single value, as mentioned in the example above, but it can also be an array:


  set foo_array = [