Inside the mind of Midnet Media.

Tricky Twig Bits: Part 1

One of the biggest hurdles to moving from Drupal 7 to Drupal 8 as a front end developer was Twig files. While in D7, the theme templates were written in HTML/PHP, Drupal 8 (as part of the adoption of symfony) has moved to using Twig for templating.

So to help my site-builder, themer, front-end Drupal developer colleagues, here’s part one of my Tricky Twig Bits series.

The Ternary & Null Coalescing Operators

Official Documentation - My Github Gist

One of my biggest goals when writing out a template file is to have the file be as simple, straight-forward, and foolproof as possible. To that end, it’s preferable to format your code in ways that balance readability and brevity. For example, consider the following:

The code below is simple and straightforward, but it spans 5 lines and has a lot of noise in there with the twig tags.

{% if boolean %}
{% set var = "value_A" %}
{% else %}
{% set var = "value_B" %}
{% endif %}

Using a code editor with nice syntax highlighting would help with readability, but writing basic if/else statements can get out of hand quickly. Imagine trying to add a handful of classes conditionally - those 5-line chunks stack up fast! A better way would be to use the ternary operator.

{% set var = boolean ? value_A : value_B %}

So much better! In a single line of code, we can see:

  • The variable we’re setting
  • The condition we’re testing
  • The value if true
  • The value if false

Additionally, ternary operators can be used to conditionally print strings. For example, under a traditional if/else block:

/*
* Add "hidden" attribute if is_hidden = TRUE
*/
{% if is_hidden %}
<div hidden>
{% else %}
<div>
{% endif %}
<p>Lorem Ipsum</p>
</div>

Again, 5 lines to simply add the hidden attribute. But with a ternary:

<div {{ is_hidden ? "hidden" : "" }}>
<p>Lorem Ipsum</p>
</div>

Suddenly, we’re down to one line of code and it doesn’t interfere with properly structured HTML.

There’s even shorthand for cases like this where we only care if the boolean evaluates one way or the other. Here’s the quick version:

/* Test & set/print based on true or false */
boolean ? val_if_true : val_if_false

/* Test and set/print only if true */
boolean ? val_if_true

/* Test and set/print only if false */
boolean ?: val_if_false

And again, the Official Documentation and My Github Gist.


Related Articles