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.
You can override Drupal core templates by adding templates to your theme folder that follow a specific naming convention.
To override templates you:
- 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.
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 core, modules, theme engines and themes can provide the suggestions. You can add or modify suggestions using the hooks:
hook_theme_suggestions_alter(array &$suggestions, array $variables, $hook)
hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables)
When working with theme hook suggestion, 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.
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 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--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.
Differences with Drupal 7
Previously to alter template suggestions, you altered
$variables['theme_hook_suggestions'] in preprocess functions to introduce theme suggestions. In Drupal 8, modules and themes now define and alter theme suggestions in their own dedicated hooks.
Change record New hooks for theme suggestions