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 shown as output within a custom theme. There are templates for each page element ranging from high-level HTML to small fields.
Overriding templates
You can override Drupal core templates or contributed modules templates by adding templates to your theme folder that follow a specific naming convention.
To override templates you need to:
- Locate the template you wish to override.
- Copy the template file from its base location into your theme folder.
- (optionally) Rename the template according to the naming conventions in order to target a more specific subset of areas where the template is used.
- Modify the template to your liking.
Once you copy a template file into your theme and clear the cache, Drupal will start using your instance of the template file instead of the base version.
You can find out what templates are in use for any part of the page by using the Twig debugging tools.
Get more specific Twig suggestions
If you want to make changes to an element, but only some places, and need more specific template suggestions for forms and elements such as buttons, input field, labels, etc., you can use these modules:
There's also Themable forms, though it may get migrated into another module and deprecated, see #3057386: Merge into Twig Template Suggester.
Theme hook suggestions
Sometimes you want to make changes to a template file, but only for some of the places that it's used. A common example is making changes to the node template file for only nodes of a specific type. Drupal's theme layer allows you to target specific use cases of a template file by following a specific naming convention. When rendering an article node Drupal will first look for the node--article.html.twig template file and use it if it exists. If it doesn't, Drupal will fall back to the default node.html.twig template. The process by which Drupal determines what possible names a template file could use is called theme hook suggestions.
Theme hook suggestions allow you to implement targeted overrides in your theme for template files with a specific naming convention.
All layers from the core, modules, theme engines, and themes can provide suggestions. You can add or modify suggestions using the hooks:
hook_theme_suggestions_HOOK(array $variables)
hook_theme_suggestions_alter(array &$suggestions, array $variables, $hook)
hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables)
For best results, here are a couple of tips. The $suggestions
array elements should only be submitted with underscores, not hyphens. Identify the needed theme hook (the Twig debugger mode will show this in your browser HTML source). Then only use that string plus two underscores, then your additional custom statement. For example, if the theme hook is called 'bob,' inside your YOURTHEME.theme file:
function YOURTHEME_theme_suggestions_bob_alter(array &$suggestions, array $variables, $hook) {
$element = $variables['element'];
$settings = $element['#settings'];
if (!empty($settings['field_name'])) {
$suggestions[] = 'bob__' . strtr($settings['field_name'], '-', '_');
}
}
Use strtr function to clean out any hyphens and replace them with underscores. if you use $suggestions[] = 'bobstring__' .
then the twig template may not load, because the theme hook is not by itself, before the double-underscores.
Rebuild cache
When working with theme hook suggestions, there is a possibility that Drupal uses its cache rather than the new templates as suggested. Clear the cache if you experience this problem. To clear the cache, choose one of the methods described in Clearing Drupal's cache.
Background information
You can think of the suggestions as naming hints telling the system to pick and choose based on the right circumstances.
The template suggestions are set through theme suggestion hooks which can be altered. These hooks allow any module or theme to provide alternative theme functions or template name suggestions and reorder or remove suggestions provided by hook_theme_suggestions_HOOK() or by earlier invocations of this hook.
How Drupal determines page theme hook suggestions based on path
Here is another explanation based on the theme_get_suggestions() function:
The list of possible templates for a given page is generated by Drupal through the theme_get_suggestions() function, which is called by the system_theme_suggestions_page() function.
The Drupal path of the page is first broken up into its components. As mentioned above, the Drupal path is not any of its aliases: there is one and only one Drupal path for a page. For the examples "http://www.example.com/node/1/edit" and "http://www.example.com/mysitename?q=node/1/edit", the Drupal path is node/1/edit, and its components are "node", 1, and "edit".
Next, the prefix is set to "page". Then, for every component, the following logic is followed:
- If the component is a number, add the prefix plus "__%" to the list of suggestions.
- Regardless of whether the component is a number or not, add the prefix plus "__" plus the component to the list of suggestions.
- If the component is not a number, append "__" plus the component to the prefix.
After the list of components is iterated through, if the page is the front page (as set through "Administration > Configuration > System > Site information."), then "page__front" is added to the list of suggestions.
Note that eventually, to turn a suggestion into an actual file name, "__" gets turned into "--", and ".html.twig" gets appended to the suggestion. Thus, for node/1/edit, we get the following list of suggestions:
page.html.twig
(this is always a suggestion)page--node.html.twig
(and prefix is set to page__node)page--node--%.html.twig
page--node--1.html.twig
(prefix is not changed because the component is a number)page--node--edit.html.twig
(and prefix is set to page__node__edit)page--front.html.twig
(but only if node/1/edit is the front page)
When the page is actually rendered, the last suggestion is checked. If it exists, that suggestion is used. Otherwise, the next suggestion up is checked, and so on. Of course, if none of the overriding suggestions exist, page.html.twig is the final suggestion. This also explains why page--front.html.twig, if it exists, overrides any other suggestion for the front page: it is always the last suggestion for the page designated as the front page.
How to add a page template for a content type
Drupal does not automatically detect page templates for content types purely based on the naming convention. To add a page template for a content type, add this in your example.theme file (replace "example"):
/**
* Implements hook_theme_suggestions_page_alter().
*/
function example_theme_suggestions_page_alter(array &$suggestions, array $variables) {
if ($node = \Drupal::routeMatch()->getParameter('node')) {
$suggestions[] = 'page__' . $node->bundle();
}
}
Now, you get suggestions in the source for content type as well. Before:
<!-- FILE NAME SUGGESTIONS:
* page--node--336.html.twig
* page--node--%.html.twig
* page--node.html.twig
x page.html.twig
-->
After (with the file page--article.html.twig also created) in the source:
<!-- FILE NAME SUGGESTIONS:
x page--article.html.twig
* page--node--336.html.twig
* page--node--%.html.twig
* page--node.html.twig
* page.html.twig
-->
Differences with Drupal 7
Previously to alter template suggestions, you altered $variables['theme_hook_suggestion']
and $variables['theme_hook_suggestions']
in preprocess functions to introduce theme suggestions. Since Drupal 8, modules and themes now define and alter theme suggestions in their own dedicated hooks.
More information
Change record New hooks for theme suggestions
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion