Twig in Drupal Core

Drupal's templating system is moving to Twig with Drupal 8, due for release later in 2013. It is more a secure and better supported approach than PHPTemplate.
Apart from minor changes to the theme file structure, the templates themselves no longer allow PHP to be embedded, with a list of predefined tags (for control structures) and extendable functions and variables to render output.

Last week it was announced that Twig will be incorporated into the next release of Drupal, version 8, due for release later in 2013. There's still a lot of work to do, but I thought I'd scratch around to see what the significance is of this big change to Drupal theming, and why it should be of interest.

Drupal has used a templating system in order to separate business logic from the presentation layer. In practice, it means building the content of the website, and it's presentation separately; the site can also have a theme updated periodically, without directly affecting the functionality or content of an existing site. Up until Drupal 7 the PHPTemplate system had been used to generate Drupal themes.

What is Twig?

To quote the Twig website:

Twig is a modern template engine for PHP:

  • Fast: Twig compiles templates down to plain optimized PHP code. The overhead compared to regular PHP code was reduced to the very minimum.

  • Secure: Twig has a sandbox mode to evaluate untrusted template code. This allows Twig to be used as a template language for applications where users may modify the template design.

  • Flexible: Twig is powered by a flexible lexer and parser. This allows the developer to define its own custom tags and filters, and create its own DSL.

It's also worth pointing out that Twig is written by Fabien Potencier, creator of the Symfony framework, which has – in part – been incorporated into Drupal 8.

The main advantage will be improving security to Drupal; there are supposedly performance improvements (the templates are effectively compiled into a PHP file), but this outcome is largely dependent on work in the next few months whilst the issue queue is worked on. Twig already used by lots of other frameworks (Zend, CakePHP, CodeIgniter) and is widely supported in many IDEs: Eclipse, Netbeans, Textmate, Coda, Komodo etc, so should allow Drupal templates to be created by a wide community of designers.

How Does it Work?

The following is an example of an HTML Twig template:


<!DOCTYPE html> <html> <head> <title>My Webpage</title> </head> <body> <ul id="navigation"> {% for item in navigation %} <li><a href="{{ item.href }}">{{ item.caption }}</a></li> {% endfor %} </ul> <h1>My Webpage</h1> {{ a_variable }} </body> </html>

There are two kinds of delimiters: {% ... %} and {{ ... }}

  • {% ... %} is used to execute control statements such as for-loops. Note: not full access to PHP commands but a much more sanitised – and safer – set of commands.

  • {{ myvariable }} prints the result of an expression to the template.

  • {# ... #} is a third delimiter, but provides comments and documentation for the template.

If you still need to do heavy processing in the theme layer (we've all done it), then you can incorporate ~~~ theme_preprocess_myvariable() ~~~ type functions into your theme.

Control and Functions

There are a limited number of commands that can be applied between the {% ... %} such as if ... then and for ... in . These are know as tags and detailed at http://twig.sensiolabs.org/doc/tags/index.html.

Functions can be called to generate content. Functions are called by their name followed by parentheses () and may have arguments. For instance, the range function returns a list containing an arithmetic progression of integers:


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

The built-in functions are listed at http://twig.sensiolabs.org/doc/functions/index.html and Twig does allow you to generate your own. You can also build macros which can then be applied to other parts of your theme.

Twig does offer maths and logic functionality too:

Maths
+ addition
- subtraction
/ Division. The returned value will be a floating point number.
% Remainder of an integer division.
// Divides two numbers and returns the truncated integer result (ie, rounded down)
* Multiplication
** Raises to the power
Logic
and
or
not
(expr): Groups an expression

Variables - Filters

Variables can be modified by filters. Filters are separated from the variable by a pipe symbol | and may have optional arguments (in parentheses). Multiple filters can be chained: the output of one filter is applied to the next. The following example outputs text and applies the Drupal translate function:


{{ "Enter your name" | t }}

Filters that accept arguments have parentheses around the arguments. A full list of filters available is at http://twig.sensiolabs.org/doc/filters/index.html.

Inheritance

One aspect that hasn't really changed is that there is inheritance, although in Twig it's a little truer to an object-oriented model, and uses the extends tag. You can also define what aspects of a parent template can be overridden by a child template, making the 'parent' theme more secure. include() can also be used to reuse components:

{% include 'core/themes/stark/templates/image/image_style.html.twig' with {image: item.image } %}

Debugging

Twig provides a dump function for debugging variables in templates, which has to be enabled in your site settings.php

$settings['twig_debug'] = TRUE;

Individual variables can be dumped, although to dump all available variables, add the following to your template:

{{ dump() }}

More information on debugging at https://drupal.org/node/1906780

Changes to File Structure

  • Naming convention for template files: block.tpl.php becomes block.html.twig.

  • Preprocess functions are stored in mytheme.theme file (goodbye template.php).

  • mytheme.info becomes a Yaml file: mytheme.info.yml - it has a very similar manifest to PHPTemplate files.

There's still a bit of tweaking to be done to get Twig fully functional in Drupal 8, so keep a close eye on the Planet Drupal. There is also some useful material to follow up in the References below. May even be an Alpha release of Drupal 8 in the very near future...