Drupal 8 Twig template engine
As you probably know, one of the best new features of Drupal 8 is the new template engine based on Twig and also used by Symfony community.
We will continue improving Bingo module so you can find all example code in the Drupal sandbox for Bingo module.
There are some changes that make better creating templates for your module pages but other things are still the same. For example we still have hook_theme:
bingo.module
/**
* Implements hook_theme().
*/
function bingo_theme() {
return array(
// Template for list of bingo participants.
'bingo_list' => array(
'template' => 'bingo-list',
'variables' => array(
'items' => array(),
),
),
);
}
As you can see the structure is the same, so you have the template name and the variables to render. The important change is that there are not theme functions anymore. All the data to build your page should be created using renderable arrays. Then you can create the renderable array for bingo participants list page this way:
lib/Drupal/bingo/BingoController.php
// Bingo participants list page.
public function content() {
$items = array();
foreach(BingoStorage::getAll() as $name) {
$items[] = l($name, "bingo/delete/$name");
}
return array(
'#theme' => 'bingo_list',
'#items' => $items,
'#attached' => array(
'css' => array(drupal_get_path('module', 'bingo') . '/css/bingo.module.css'),
),
);
}
You only need to construct the renderable array passing the theme name (bingo_list), the variables to render ($items) and attach some CSS or JS if you need it.
If you need to alter the variables or add new ones to be available in the template you can do it in the corresponding template_preprocess function. For example we can add a custom message to indicate that the participants list is empty and a couple of link to let the user add more participants or start the Bingo game:
/**
* Preprocess variables for list of bingo participants page.
*
* @param array $variables
* An associative array containing:
* - items: Array of participant names.
*/
function template_preprocess_bingo_list(&$variables) {
// Check if there are participants.
// If not add a default message.
if (empty($variables['items'])) {
$variables['items'][] = t('No participants found. Please add participants.');
}
$variables['add_link'] = l(t('Add'), 'bingo/add');
$variables['play_link'] = l(t('Play'), 'bingo/play');
}
You only need to add the new variables in the $variables array. And now you can create the twig template and display the variables with your cool markup. The template name should be the same you entered in hook_theme() function followed by html.twig as you can see:
templates/bingo-list.html.twig
<section class="bingo">
<ul class="bingo-items">
{% for item in items %}
<li class="bingo-item">{{ item }}</li>
{% endfor %}
</ul>
<aside class="bingo-links">
{{ add_link }}
{{ play_link }}
</aside>
</section>
Twig syntax is more readable than the old phptemplate syntax. Twig also include some helper functions, filters and operands that make theming really easy. Take a look at Twig documentation for more info.
Don't forget that this new Drupal 8 feature is being developed thanks to some awesome contributors. The Twig initiative guys are working hard to bring you a cleaner and more maintainable markup inside twig templates. So if you want to learn more about the initiative and help contributing to the Drupal community just join them in the regular meetings or the #drupal-twig IRC channel.
See you in the next post where I will show you how to deal with other new Drupal 8 feature: Plugins.