In our custom theme’s current state, we’re using Classy’s template files as-is. If we want to customize any of these templates, we need to override them with Twig files located in our custom theme’s templates
directory.
Twig is a template engine with syntax similar to Django, Jinja, and Liquid. It simplifies template creation with clean syntax and useful build-in filters, functions, and tags. In a Drupal template file (now with the extension .html.twig
), anything between {{ ... }}
or {% ... %}
or {# ... #}
is Twig.
{{ These }}
are for printing content, either explicitly or via functions
{% These %}
are for executing statements
{# These #}
are for comments
Printing variables and regions
In Drupal 7 we render content like so:
<?php print render($page['sidebar']); ?>
Printing variables using Twig in D8 is as easy as including them in the double curly brace delimiter.
// In page--front.html.twig
// Print the sidebar region.
{{ page.sidebar }}
…unless there are special characters in the variable name. If that’s the case and you see an error when using the syntax above, you can use Twig’s subscript syntax, which should look pretty familiar to Drupalers:
// In page--front.html.twig
// Print the page type.
{{ page['#type'] }}
This will be more useful when debugging. The Drupal core base themes include lists of available variables and regions in the DocBlock of their template files, or you can print variables to the page via Twig’s debug mode (more on that below) to see what’s available to you.
Filters and functions
Twig comes with many built-in filters that variables are passed to via the pipe character. These filters do many of the things that PHP functions would have in previous Drupal versions. One example is the date filter:
// Format the post date.
{{ post.published|date("Y-m-d") }}
There are also Drupal-specific Twig filters, such as t
which runs the string through the t()
function.
// Run an ARIA label through t()
<nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
By the way, ARIA labels are new in Drupal 8 too!
In addition to filters, Twig provides a range of functions that are also used within the double curly brace delimiters.
Control flow and other tags are also supported in Twig. One of my favorite things about templating languages is how easy it is to execute if
statements and for
loops. Savas Labs uses Jekyll for our company website and the Liquid templating language makes it easy to loop through a list of data points, blog posts, projects, etc. and print them to a page rather than writing out all of the HTML. In Drupal, we’ll use the if
statement quite often.
// From Bartik's page.html.twig
// If there are tabs, output them.
{% if tabs %}
<nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
{{ tabs }}
</nav>
{% endif %}
Another useful tag is set
, which allows you to set and use variables throughout the template. In the following example, the variable heading_id
is set and then used as the aria-labelledby
attribute. Note that the Twig concatenation character ~
is used, and the string ‘-menu’ is passed through the clean_id
filter.
// From Classy's block--system-menu-block.html.twig
{% set heading_id = attributes.id ~ '-menu'|clean_id %}
<nav{{ attributes.addClass(classes) }} role="navigation" aria-labelledby="{{ heading_id }}">
Coding standards
Since this is new to some Drupalers, take a moment to check out the coding standards for Twig.