From Working With Twig Templates:
Drupal allows you to override all of the templates that are used to produce HTML markup so that you can fully control the markup that is being output within a custom theme. There are templates for each page element ranging from the high level HTML to small fields.
To enable Twig Debug Mode
:
- If
sites/default/services.yml
exists proceed to next step. Otherwise copysites/default/default.services.yml
tosites/default/services.yml
. - Edit
sites/default/services.yml
. - Under
twig.config
section, setdebug: true
. - Clear cache either by clicking
Clear all caches
on/admin/config/development/performance
or runningdrush cr
on the command line.
Once enabled you can use dump()
to output all available variables or output contents of a particular variables:
All variables:
{{ dump() }}
Contents of `foo`:
{{ dump(foo) }}
When Twig debug mode is enabled, Drupal will suggest a few possible ways to override the markup and preprocessor for particular content blocks. This will be shown in the page HTML as comments.
For example:
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
* block--substable-content.html.twig
* block--system-main-block.html.twig
* block--system.html.twig
x block.html.twig
-->
If you wish you make your own recommendations, you hook into the preprocessor for this particular element and make your own additional suggestions.
<?php
/**
* Implements hook_theme_suggestions_block_alter() for block templates.
*/
function substable_theme_suggestions_block_alter(array &$suggestions, array $variables) {
$suggestions[] = 'block__substable';
$suggestions[] = 'block__substable__' . $variables['elements']['#id'];
}
?>
If you clear your cache and look again at the comments you should see the new suggestion in the list.
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
* block--substable--substable-content.html.twig
* block--substable.html.twig
* block--substable-content.html.twig
* block--system-main-block.html.twig
* block--system.html.twig
x block.html.twig
-->
Now you can create templates/block--substable.html.twig
or block--substable--substable-content.html.twig
, to override core block behavior.
The earlier a file name is in the file name suggestions above, the higher priority it will have. So by pushing to the end of the suggestions array, we are setting our template suggestions to have the highest possible priority.
Make sure you clear your cache after creating any new template files.
From twig.symfony.com - include:
The include statement includes a template and returns the rendered content of that file into the current namespace:
{% include 'header.html' %} Body {% include 'footer.html' %}
Included templates have access to the variables of the active context.
You can add additional variables by passing them after the with keyword:
{# template.html will have access to the variables from the current context and the additional ones provided #} {% include 'template.html' with {'foo': 'bar'} %} {% set vars = {'foo': 'bar'} %} {% include 'template.html' with vars %}
You can disable access to the context by appending the only keyword:
{# only the foo variable will be accessible #} {% include 'template.html' with {'foo': 'bar'} only %} {# no variables will be accessible #} {% include 'template.html' only %}
From twig.symfony.com - extends:
The extends tag can be used to extend a template from another one. Let's define a base template, base.html, which defines a simple HTML skeleton document:
<!DOCTYPE html> <html> <head> {% block head %} <link rel="stylesheet" href="style.css" /> <title>{% block title %}{% endblock %} - My Webpage</title> {% endblock %} </head> <body> <div id="content">{% block content %}{% endblock %}</div> <div id="footer"> {% block footer %} © Copyright 2011 by <a href="http://domain.invalid/">you</a>. {% endblock %} </div> </body> </html>
In this example, the block tags define four blocks that child templates can fill in.
All the block tag does is to tell the template engine that a child template may override those portions of the template.
A child template might look like this:
{% extends "base.html" %} {% block title %}Index{% endblock %} {% block head %} {{ parent() }} <style type="text/css"> .important { color: #336699; } </style> {% endblock %} {% block content %} <h1>Index</h1> <p class="important"> Welcome on my awesome homepage. </p> {% endblock %}
The extends tag is the key here. It tells the template engine that this template "extends" another template. When the template system evaluates this template, first it locates the parent. The extends tag should be the first tag in the template.
Note that since the child template doesn't define the footer block, the value from the parent template is used instead.
- drupal.org - function hook_theme_suggestions_alter
- drupal.org - Working With Twig Templates
- twig.symfony.com - include
- twig.symfony.com - extends