Working with Twig Templates in Drupal 8
drupal.org: mikeker
"Dude, where's my car file?"
http://slides.com/mikeker/twig-templates-in-d8
Me: circa 2013
Debugging
# Uncomment these lines in settings.php
if (file_exists(__DIR__ . '/settings.local.php')) {
include __DIR__ . '/settings.local.php';
}
# Change this is sites/default/services.yml
parameters:
twig.config:
# @default false
debug: true
$ cp sites/example.settings.local.php ↵
sites/default/settings.local.php
$ drush cache-rebuild # alias: drush cr
# Uncomment the following line in settings.local.php
$settings['cache']['bins']['render'] = 'cache.backend.null';
https://www.flickr.com/photos/tsevis/
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
* field--node--body--page.html.twig
* field--node--body.html.twig
* field--node--page.html.twig
* field--body.html.twig
x field--text-with-summary.html.twig
* field.html.twig
-->
<!-- BEGIN OUTPUT from 'core/themes/classy/templates/↵
field/field--text-with-summary.html.twig' -->
... Template output goes here ...
<!-- END OUTPUT from 'core/themes/classy/templates/↵
field/field--text-with-summary.html.twig' -->
Drupal Template Helper
https://github.com/arshad/drupal-template-helper
Template file location
-core
-modules
-themes
|-contrib
|-custom
|-example_theme
|-...
|-templates
|-field.html.twig
|-field--field-custom-field.html.twig
|-node.html.twig
|-node--article.html.twig
|-...
-core
-modules
-themes
|-contrib
|-custom
|-example_theme
|-...
|-templates
|-fields
|-field.html.twig
|-field--field-custom-field.html.twig
|-nodes
|-node.html.twig
|-node--article.html.twig
|-...
Theme suggestions
// Drupal 7 version
function HOOK_preprocess_views_view(&$variables) {
if ($variables['name'] == 'my_view') {
$variables['theme_hook_suggestions'][] =
'my_view_template';
}
}
// No more singular -- this does not work in Drupal 8:
$variables['theme_hook_suggestion'] =
'node__' . 'use_this_one';
In Drupal 8 we have:
-
hook_theme_suggestions_alter()
-
hook_theme_suggestions_HOOK()
-
hook_theme_suggestions_HOOK_alter()
hook_theme_suggestions_alter
function MYTHEME_theme_suggestions_alter(array &$suggestions, ↵
array $variables, $hook) {
if (\Drupal::currentUser()->isAuthenticated() &&
in_array($hook, array('node', 'taxonomy_term'))) {
$suggestions[] = $hook . '__' . 'logged_in';
}
}
Views, as an example
https://www.drupal.org/node/2118743
Adding Options
function MYTHEME_theme_suggestions_views_view_alter ↩
(array &$suggestions, array $variables) {
$display = $variables['view']->getDisplay()->getPluginId();
$view = $variables['view']->id();
$suggestions[] = "views_view__$view";
$suggestions[] = "views_view__$display";
$suggestions[] = "views_view__$view" . "__$display";
}
Preprocessing
Template: field.html.twig
mytheme_preprocess_field(&$variables)
Template: field--field-name.html.twig
mytheme_preprocess_field__field_name(&$variables)
Template: node--node-type--view-mode.html.twig
mytheme_preprocess_node__node_type__view_mode(&$variables)
Template Reuse
The old way
{# You could do this in each field template override... #}
{# File: templates/field--field-list.html.twig #}
<div{{ attributes }}>
<ul class="{{ classes | join(' ') }}">
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</div>
A better way...
{# Super simplified list example #}
{# File: templates/list.twig #}
{% set listType = listType ?? 'ul' %}
{% set classes = classes ?? ['default', 'classes'] %}
<div{{ attributes }}>
<{{ listType }} class="{{ classes | join(' ') }}">
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</{{ listType }}>
</div>
{# File: templates/field--field-name.html.twig #}
{% include '@theme_name/lists.twig' %}
A better way, continued...
{# File: templates/field--field-name.html.twig #}
{% include '@test/lists.twig' with {
listType: 'ol',
classes: ['my', 'new', 'classes'],
}%}
Why?
{# File: template/lists.twig #}
{% set listType = listType ?? 'ul' %}
{% set classes = classes ?? ['default', 'classes'] %}
<div{{ attributes }}>
{% if items | length == 1 %}
{{ items }}
{% else %}
<{{ listType }} class="{{ classes | join(' ') }}">
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</{{ listType }}>
{% endif %}
</div>
Any questions?
Working with Twig Templates in Drupal 8
By Mike Keran
Working with Twig Templates in Drupal 8
- 1,267