The problem
Sometimes you need to create a page template for a specific content type so that you can customise it. Drupal allows you to create content types for node templates out of the box by following the naming convention node--content-type.html.twig
. But things aren’t so simple for page templates. Drupal does not automatically detect page templates for content types purely based on the naming convention. Fortunately it just takes a few lines of code and you can create a page template for any content type you choose.
Before we start, let’s take a brief look at the difference between a node and a page template.
Page: the template that controls the whole page. This will include a $content variable, which after rendering will be the node. Node: the template that controls just the content part of the page.
A solution
To tell Drupal to use the page template for a content type, you can implement hook_theme_suggestions_page_alter()
. This hook is used whenever a page.tpl.php template is used and allows you to suggest alternative templates.
In this case, you are going to use hook_theme_suggestions_page_alter()
to tell Drupal to use a specific page template for a specific content type, instead of the default page.tpl.php.
Here is an example of how to tell Drupal to use a template for a content type. Add this code to the example.theme
file in your theme, and change hook to the name of your theme. If you have already implemented theme_preprocess_page
in your theme’s template.php, you can add the ‘if’ statement to that.
Here is the solution:
/**
* 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();
}
}
The solution explained
In this example, you are telling Drupal that you’d like to use a template with the name of the content type when a page is being viewed. Example templates include:
page--article.html.twig
for a article content typepage--gallery.html.twig
for a gallery content type
This is added to ‘theme_hook_suggestions’, which adds it to the pool of potential templates that Drupal can use. In most cases it will use this one, unless you have another template that meets a more specific criteria. For example, you might have a page template for a single node, which would be more specific and used instead. To add a new theme suggestion, implement hook_theme_suggestions_page_alter()
in your theme’s .theme
file.
Another example, if you have a theme named example
, open the file called example.theme
(or create one if it doesn’t exist). And then adding the the following function.
function example_theme_suggestions_page_alter(array &$suggestions, array $variables)
And inside that function, check that you are viewing a node with:
if ($node = \Drupal::routeMatch()->getParameter('node')) {
And finally, add the naming convention to the theme suggestions with:
$suggestions[] = 'page__' . $node->bundle();
$node->bundle();
will return the name of the content type. So the suggested page template for the article content type will be:
page__article
The complete steps
- Open
example.theme
(replace example with your actual theme name) - Add the code snippet below
- Replace
example
in the function nameexample_theme_suggestions_page_alter
with your actual theme name - Refresh the cache
The complete code in example.theme
once again is:
/**
* 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();
}
}