Adding Templates to Custom Modules
When you make an html.twig
file and add it to the templates folder of a custom theme you are pretty much done (after refreshing caches!). The Drupal theme rendering processes detect the template and uses it in preference to any template of the same name from a parent or default theme. You don't really have to do anything more than add the file and refresh cache.
But, if you add a template to a custom module -even if your intent is just to override a theme default template (e.g.field.html.twig
) or to provide a suggested template, there are a few extra things you must do.
Using the example of a custom content type (node) called "node_landing_page", the steps below fully implement a template to be used to render the nodes full
display.
Note: Drupal automatically generates the suggestion fornode__landing_page__full
which can be used for rendering the "default" (i.e. "full") display.
You can generate other suggestions using the hook_theme_suggestions_hook
hook.
Create the twig template you wish to use, and give it a name that matches an existing Drupal theme suggestion with ".html.twig" as the extension. In rare cases you may want to create a new template suggestion. Do this by returning an array of suggestions from a
hook_theme_suggestions_hook()
in your custom module (see last example below). Convention is to name the template using an "entity breadcrumb" style, with "--"'s between entities and no spaces.Save the template file in a folder called
templates
in your custom modules root folder. In our exampledocroot/modules/custom/node_landing_page/templates
. - You could organize files by creating a sub-folder tree - but if you do, you will then have to specify thepath
to your template in thehook_theme
- see step 3 below.In the
hook_theme
of your module you must define your new template. This hook is read by the Drupal core theme engine and loaded into a template cache (aka register). Whenever a change is made to this hook you need to clear all caches to load your changes into the cache. Inhook_theme
return an assoc array with key-value pair nested arrays for each template you wish to define. - The outer keys (template-keys) should be one for each of the templates you are defining. Keep it simple and traceable by setting the the template-key name to be the template filename without the ".html.twig". Important: Replace all "-"'s with "_"'s in the template-key string. (in our example the template-key isnode__landing_page_full
) - The value for the key (template-key) is an array with a requiredbase_hook
and several other optional fields. Thebase_hook
should define the entity type this template is used to render (in our casenode
but other common entities we theme arefield, region, block, paragraph, taxonomy_term
) . [optional] Therender element
defaults toelements
if not specified. [optional] If you wish to use a template file which is not the same name as the suggestion (with "_"'s replaced with "-"'s) then you must specify its name in thetemplate
field. Omit the "html.twig" extension. This could be useful if you want 2 display to share the same template. [optional] If you want to use a custom path to the template file (i.e. not the default templates folder) then use thepath
field. (seebos_link_collections_theme
in boston.gov for example) (see "Our Example hook_theme" below for the complete hook)[optional] Once the cache is cleared you can then catch pre-process events using
hook_preprocess_hook
in our example this would benode_landing_page_preprocess_node
(to catch all node pre-process events) ornode_landing_page_preprocess_node__landing_page__full
(to catch only this new template pre-process events) - notice that the hook uses thetemplate-key
defined in thehook_theme
array.[optional] You can also catch
template_preprocess_hook
events (in our example this istemplate_preprocess_node__landing_page__full
). This hook is commonly used to create acontent
variable which contains all the rendered (or renderable) elements of theelements
(or whatever the field is named in the templatesrender element
) array.
Our Example template file:
Our Example hook_theme:
Our Example hook_preprocess_hook (version 1):
Our Example hook_preprocess_hook (version 2):
Our Example template_preprocess_hook:
Our Example hook_theme_suggestions_hook:
Last updated