Demystifying Twig Syntax in Drupal 8: Unleash the Power of Templating Skip to main content

In Drupal 8

Saurabh Dhariwal

Saurabh Dhariwal

Drupal 8 - Twig

Twig is a php template engine used in drupal 8. It is fast, secure and flexible. Template files and theme functions is replaced by *.html.twig template files in D8.

  • There are basically 3 types of delimiters:

{{ }}

Print statement

{# #}

Comment statement

{% %}

Execution statement (Ex. for-loops)

  • Set Variables/Array: “Set” is used to assign values to a variable/array

{% set foo = 'bar' %}

Sets variable “foo” with value “bar”

{% set foo, bar = 'foo', 'bar' %}

Sets Multiple variable at a time.

This is equivalent to

{% set foo = 'foo' %}

{% set bar = 'bar' %}

{% set foo = [1, 2] %}

Set array “foo” with values “1” & “2”

{% set test = {'foo': 'bar'} %}

Set array “test” with key as “foo” & value as “bar”

{% set c = a ~ b %}

Concatenates string “a” & “b”. operands are converted into strings.

  • Debug

{{ dump(user) }}

Prints array if “user” is an array

 

if it is a variable then it will print variable value.

{{ dump(user|keys) }}

Prints “key” of “user”.

  • Filters

  1. Filters are separated by pipe symbol (|)
  2. Multiple filters can be chained
  3. Optional arguments appear in parentheses

{{ name|striptags|title }}

“striptags” removes all HTML tags from “name” and “title” title-cases it.

{{ 'temperature is less than 18'|t }}

“t” is used for translation of string

{{ list|join(', ') }}

Join list with comma(,)

{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}

 

Render “now”date with specific format and specific timezone

  • For Loop

          Example:

<ul>
  {% for key, user in users %}
  	<li>{{ user.username|e('html') }}</li>
  {% else %}
  	<li><em>no user found</em></li>
  {% endfor %}
</ul>
  • If Condition

Example 1:

{% if temperature < 18 %}
<p>{{ 'temperature is less than 18'|t }}</p>
{% elseif temperature > 18 and temperature < 27 %}
<p>{{ 'temperature is between 18 & 27'|t }}</p>
{% else %}
<p>{{ 'temperature is greater than 18'|t }}</p>
{% endif %}

Example 2:

{% if users | length > 0  %}
	<p>There are {{ users | length }} users available.
{% endif %}

In this example, if there are users available, then it will print the number of users available.

  • The ternary operator:  ?: is the ternary operator

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

If “foo” is set then it will return “yes” else “no”

{{ foo ?: 'no' }}

same as {{ foo ? foo : 'no' }}

{{ foo ? 'yes' }}

same as {{ foo ? 'yes' : '' }}

  • The null-coalescing operator

{{ foo ?? 'no' }}

if “foo” is defined and not null then it will return “foo” else “no”

  • String InterpolationAllows expression to appear within a string

{{ "foo #{bar} baz" }}

Value of #{bar} is replaced in the string

{{ "foo #{1 + 2} baz" }}

#{1 + 2} expression is evaluated and replaced

  • Escaping: Used to reduce risk of affecting the resulting HTML, if variable contain some special characters.

  1. Manually escaping

{{ user.username|e }}

{{ user.username|e(‘html’) }}

Default is “html” escape

{{ user.username|e('js') }}

Escape JS

{{ user.username|e('css') }}

Escape CSS

{{ user.username|e('url') }}

Escape URLs

  1. Automatically escaping

{% autoescape %}
   Automatically escaping text.
{% endautoescape %}

Default is “html” escape

{% autoescape 'js' %}
   Automatically escaping text.
{% endautoescape %}

Auto Escape ‘js’

  • IncludeInclude a rendered content of one template into another template.

{% include 'header.html.twig' %}

This is used to include “header.html.twig” in any other file.

  • Macros

  • Used to reuse html code

  • Define macro tag (forms.html):

{% macro input(name, value, type, size) %}
	<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}

In above example “Type” default value is set to “text” and “size” default value to “20”. It can also be defined as:

{% macro input(name, value = "", type = "text", size = 20) %}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
{% endmacro %}

Import macro in different file, and then use it:

{% import "forms.html" as forms %}
<p>{{ forms.input('username') }}</p>

  • Import individual macro names with alias:
{% from 'forms.html' import input as input_field %}
<p>{{ input_field('username') }}</p>

  • Import macro into same file:
{% import _self as forms %}
Hope this helps you all. Feel free to leave valuable feedbacks regarding the same.