Accueil / Blog / Métier / 2015 / Howto: using Twig in Drupal 7

Howto: using Twig in Drupal 7

Par Sébastien Corbin publié 25/06/2015
Using Twig in Drupal 7 is indeed possible: here's how to anticipate Drupal 8, and use right now the theme engine bundled in the next version of our favorite CMS.
Howto: using Twig in Drupal 7

Introduction

The concept of template engine goes back to Drupal 4.6, but was rarely used due to the majority of contrib themes using the default template engine, PHPTemplate.

Yet, some integrations were made:

  • Smarty
  • PHPTal
  • XSL
  • ETS
  • Haml

And now Twig !

Some reminders about Twig syntax

Twig provides a more simple syntaxe than PHPTemplate's, 3 tags are to be known: {{ }} to display a variable or an expression, {% %} for logical operations logiques and {# #} for comments.

Full documentation is available at http://twig.sensiolabs.org/doc/templates.html

Variables display

Forget arrows, square brackets, quotes in <?php echo $node->field_myfield['und'][0]['entity']->title; ?>, you can now use dots like in {{ node.field_myfield.und.0.entity.title }}.

Naturally, you are not to display raw values in a template, but you should render the arrays returned by field formatters instead. Put simply, instead of writing
<?php echo render($content['field_myfield']; ?>, you should do {{ content.field_myfield }}

Logical structures

With PHPTemplate, you avoid PHP warnings and notices while display a non-existent variable or array index by wrapping it in a <?php if(!empty($content['field_myfield'])): ?>; with Twig, you can simply write {% if content.field_myfield %} and close it with {% endif %}

Foreach loops <?php foreach($content['field_myfield'] as $item): ?> are to be transformed to {% for item in content.myfield %} and closed with {% endfor %}. In this loop, you can display the current index with {{ loop.index }} or test for example the first item with {% if loop.first %}

Functions

Functions are available like other template inclusion (with some context)
{{ include('template.html', {mavariable: 'savaleur'}) }} or variable content display with {{ dump(variable) }}, note that if Devel is enabled, content will be shown in a Krumo block.

Filters

Filters are applied on variables, notables ones are date that converts a timestamp or a datestring to a specified format {{ node.created|date("m/d/Y") }}, length that returns the length of an array or a string {{ table|length }}, trim that strips whitespaces at the beginning or the end of a string and replace that replaces string parts.

Installation

TFD7

The theme engine is currently on Github, its documentation is on http://tfd7.rocks/, it has dependencies over the X-Autoload and Libraries API modules, and the Twig library available on Github.

Once downloaded, you can run the post-install.php file which will move over the directories to the right locations, or move engines in sites/all/themes and rename to have sites/all/libraries/TFD/TFD

drush en libraries xautoload -y
cd sites/all/libraries
wget https://github.com/twigphp/Twig/archive/v1.18.2.tar.gz
untar v1.18.2.tar.gz
mv Twig-1.18.2 Twig
git clone https://github.com/TFD7/TFD7.git
mv TFD7 TFD
mv TFD7/engines ../themes

Then you can add the property in the .info file of your theme

engine = twig

You can then create templates file with '.tpl.twig' extension in it.

Base theme feature (Bootstrap example)

For now, it is impossible to have a base theme having a different theme engine from the sub-theme, as it will always be the theme engine of the base theme that will be taken into account (see this issue).

To work with a subtheme like Bootstrap, you have to cheat and alter Bootstrap's theme engine:

/**
 * Implements hook_system_info_alter().
 */
function mymodule_system_info_alter(&$info, $file, $type) {
  // Tweak bootstrap so it would be considered as a twig-based theme.
  if ($type == 'theme' && $info['name'] == 'Bootstrap') {
    $info['engine'] = 'twig';
  }
}

The only problem is that Bootstrap's '.tpl.php' files are no longer discovered, but thelist is quite small, especially if you are building a front-end theme

./bootstrap/theme/block/block-admin-display-form.tpl.php
./bootstrap/theme/block/block.tpl.php
./bootstrap/theme/bootstrap/bootstrap-modal.tpl.php
./bootstrap/theme/bootstrap/bootstrap-panel.tpl.php
./bootstrap/theme/search/search-block-form.tpl.php
./bootstrap/theme/system/html.tpl.php
./bootstrap/theme/system/page.tpl.php
./bootstrap/theme/system/progress-bar.tpl.php

You can find the main Bootstrap templates converted to Twig, it's free :)

Warning: Bootstrap messed up the theme registry in the version 7.x-3.1, so be sure to use the 3.0 version (see https://www.drupal.org/node/2624216).

Don't hesitate to contribute to the project if you find bugs or missing features!

ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
The state of localize.drupal.org in 2014 30/01/2014

A summary about the current situation of the Drupal localization project.

Desperately seeking drupal modules Desperately seeking drupal modules 23/06/2013

A customized Google query to quickly find Drupal modules.

Drupal, Bootstrap, LESS & Gulp : how to make a Drupal theme Drupal, Bootstrap, LESS & Gulp : how to make a Drupal theme 15/09/2014

More and more articles with these words are appearing right now: here's our approach for a ...

Challenges of maintaining a highly-used Drupal module Challenges of maintaining a highly-used Drupal module 02/03/2011

A story of a Drupal contrib maintainer.

Drupal and SEO: HowTo Drupal and SEO: HowTo 21/11/2013

A subjective (but well-argued) review of modules that you can use to properly add SEO to your ...