Twig Tricks You Need To Know

If you are developing in Drupal 8, then you probably have come across the switch to Twig for all templating. Twig is a powerful PHP template engine that allows for clean, easy to learn, templating for your Drupal 8 site.

Combined with your yourtheme.theme file, Twig allows you to have significant control over the front end of your Drupal 8 site. While extensive documentation can be found on SensioLabs, here are 10 of my favorite Twig functions and filters to get you on your way to exploring the power of Twig:

1. Add a class to the {{ attributes }}  variable in a Twig template.

When looking at any twig template, you will notice an {{ attributes }} variable. This is used to add classes, IDs, and other attributes to a piece of content. If you ever need to alter to this variable, you can so by adding a few lines in your yourtheme.theme file: 

Example: If the sponsored field is checked, add a class of “is-sponsored” 

function yourtheme_preprocess_node(&$variables) {
if (isset($sponsored_field)) {
$variables['attributes']['class'][] = 'is-sponsored';
}
} 

Note: you can also add a class to the {{ attributes }} variable by doing the following in your twig template: 

{{ attributes.addClass(‘my-awesome-class’) }}

However, the first method is a little cleaner because it allows you to add a class without creating a template, which I prefer in most cases. 

2. How to check if a field has content with Twig

While a seemingly simple task, this is actually one of the harder things to do in twig. In Twig, there are a number of ways to check if a variable is defined or not. Since fields are used like variables in a template, the approach is similar. 

In order to accurately check if a field is populated, you need to use a combination of filters and loops: 

Example: If the node has an image, display in a two column layout. Otherwise, display in a one column layout. 

First, we check if there is a person field, then we check if that field has any content by rendering the field, then trimming the field of anything that twig could confuse as content (such as whitespace). 

{% if content._field_layout.content.field_person_image is defined and content._field_layout.content.field_person_image|render|trim %} 
Two columns
{% else %}
One column
{% endif %}

Note: In the case of a non-image field, I have found you often need to add a |striptags filter to the field variable to get an accurate reading if the field is empty or not: 

{% if content._field_layout.content.field_author|render|striptags|trim is defined and content._field_layout.content.field_author|render|striptags|trim is not empty %}

3. Using |without to render fields

As a rule, I try to avoid hard coding fields in a template. It can be annoying to debug and maintain and makes your twig templates messy. However, when you can’t avoid it here is my favorite filter that can make things easier: 

Example: You want to render all the fields defined in the drupal Display Mode except for the image:

{{ content._field_layout.content|without('field_image') }}


This way, you do not have to print out every single field in the template, allowing you to still add additional fields in the future through the Display Mode without adjusting this template. 

4. Creating a Basic Twig variable 

We can use {% set %} to create our own variables directly in a twig template, without ever needing to touch the `.theme` file. 

Option one: 

To create a simple variable based off of the value of a field: 

Example: Make a class out of the selected background color from the Background Color field 

{% set bg_color = 'color-' ~ content['#block_content'].field_background_color.value %}
  • bg_color is the variable name.  Can be used like {{ attributes.addClass( bg_color ) }} or class = “{{ bg_color }}” 

  • ‘Color’~ is being prepended to the value of the background color field (example: color-black) 

  • Result: color-blue

5. Creating a Conditional Twig Variable 

 

To create a conditional variable, using a ternary statement: 

{% set full_width = (region_name  === 'featured_middle') ? 'full-width' : '' %}
  • full_width is the variable name 

  • If the region_name (this is an existing twig variable) is featured middle, set the variable class to “full-width”. Otherwise, leave the variable empty.

6. Rendering a Block or View in Twig

Using the Twig Tweak module, you can call views and blocks in a twig template. 

Block: 

{{ drupal_block('plugin_id') }} 

or a block without the wrapping div: 

{{ drupal_block('plugin_id', wrapper=false) }}

View block:

{{ drupal_view('who_s_new', 'block_1') }}

7. Twig comma separated list

Add commas, or any other separators, between a list of elements. This is useful for multi-value fields (taxonomy terms, dates, links).

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

8. Twig {% for %} loop

For any multi-value field or plain array field, you can loop through each item individually by doing the following: 

Example:

items = ‘apple, orange, banana’
{% for item in items %}
<div class=”my-cool-class”>{{ item }}</div>
{% endfor %}

 

This outputs as: 

<div class=”my-cool-class”>apple</div>
<div class=”my-cool-class”>orange</div>
<div class=”my-cool-class”>banana</div>

9. Find position in a twig array

When creating patterns, it is useful to find position within an array in order to add classes, or adjust layout. 

Example: After the third item, insert a label:

{% if loop.index > 2 %}
Check out our other resources!
{% endif %}

Example: Create a unique ID for each element:

<div class id=”field-item-{{ loop.index }}”>

10. Creating patterns or batches from a twig array

When creating tables, or grouped patterns, you can split out items in an array into “batches” using the twig batch filter: 

<table>
{% for row in items|batch(3, 'No item') %}
<tr>
{% for column in row %}
<td>{{ column }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Resources

These are just a few useful ways you can get started theming your Drupal 8 site with Twig. For your further education, here are some of my favorite Twig resources: