How to add custom page and html twig templates to Drupal 8 and 9 theme
Here we are going to discuss different ways of creating custom page and html templates using theme suggestions. Here we are going to decide which html or page template need to rendered based on few conditions.
By default, all pages are rendered in below below templates.
\core\themes\classy\templates\layout\html.html.twig
\core\themes\classy\templates\layout\page.html.twig
You can see from which theme above templates are rendering by enabling twig debug in services.yml. Read more about development configurations in this article.
All nodes of different content types will be rendered through above templates.
If you want changes in above templates you have to place above files in your theme path a shown below. now you can apply your theme specific changes to below files.
YOUR_THE_FOLDER\templates\layout\html.html.twig
YOUR_THE_FOLDER\templates\layout\page.html.twig
Here we are going to create custom templates like page –article.html.twig etc. In our custom theme. Also we will discuss customization in html.html.twig
We are going to discuss below points.
• Page template theme suggestion based on content type
• Html template(html.html.twig) customization using theme suggestion
• Separate page template for nodes in same content type using theme suggestion
Page template theme suggestion based on content type
Here we are rendering separate page.html.twig for each content type. Suppose we need a separate page twig file for article. So we need to create a page–article.html.twig.
In order to render all article nodes in template page–article.html.twig, provide below template suggestion in hook_theme_suggestions_page_alter
function dn_agri_theme_suggestions_page_alter(array &$suggestions, array $variables) { if ($node = \Drupal::routeMatch()->getParameter('node')) { $suggestions[] = 'page__' . $node->bundle(); } }
dn_agri is my theme name.
Here $node->bundle() will be the article if you are opening a page of article content type.
So page suggestions has page__article a as template, so our template file name would be page–article.html.twig.
You can verify this by placing page.html.twig from classy theme or from your parent them in your theme templates folder.
Here I have copied file in to my theme template and renamed file page–article.html.twig
\themes\custom\my_theme\templates\system\page–article.html.twig
So, in order to identify which template is rendering , I have placed article-container class in div. Also buy enable twig debug you can see template name in your browser view source page.
. After clear the cache open a article page, you can confirm which page twig is rendering by below class name.
we can test this by creating an new content with URL path alias as well , it will render in new template file.
See below theme path in view source of the article content page.
Html template(html.html.twig) customization using theme suggestion
Similar way we can customize html.html.twig file. Here we are rendering article contents in html–article.html.twig file.
Copy html.html.twig file from parent theme and place it in your theme as below
\themes\custom\YOUR_THEME\templates\system\html–article.html.twig
You can get parent template as below from browser view source. in my case it is rendered from bootstrap theme.
Provide below html_alter hook in your *.theme file.
** * /* implement hook */ function {YOUR-Theme-Name}_theme_suggestions_html_alter(array &$suggestions, array $variables) { if ($node = \Drupal::routeMatch()->getParameter('node')) { $suggestions[] = 'html__' . $node->bundle(); } }
So above code will add html–{contentType} template to the theme suggestion and render all article content through html–article.html.twig
Clear the cache and open the article content page.
If you would have enabled twig debug you can see below template in your browser.
Separate page template for nodes in same content type
There will be requirements where you have to create separate page template for nodes under same content type. In that case you can use template suggestion based on some of the conditions.
For this, create a taxonomy with terms. Here we have below templates taxonomy.
For each term, template name is provided in description filed as below.
Next add this taxonomy as a filed in article content type. Here we have created Lay out field with taxonomy templates as relationship.
So while adding a article content, user can select lay out.
Next , create below template file in templates folder.
\themes\custom\YOUR_THEME\templates\system\page–article–page–1.html.twig
You can customize and arrange html tags based what you are expecting in col 1 page template .
In our *.theme file, we have to map page template file based on what layout selected by the user.
Provide below code in your page alter hook in .theme file.
function [theme_name]_theme_suggestions_page_alter(array &$suggestions, array $variables) { if ($node = \Drupal::routeMatch()->getParameter('node')) { if(!empty($node->hasField('field_lay_out'))) { $tid = $node->get('field_lay_out')->getValue()[0]['target_id']; if(!empty($tid)){ $term_object = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($tid); $term_name = $term_object->get('description')->getValue()[0]['value']; $template_var = trim('page__' . $node->bundle().'__'.strip_tags($term_name)); $suggestions[] = $template_var; } } } }
Here field_lay_out is the machine name of Lay out field.
Above code will assign page__article__page__1 to the suggestions variable if user selects Col1 value in lay out field.
Clear the cache and add an article content with field selected as Col1. You can see new template in browser as below.
Also read below articles for view and node template customizations.
How to customize results of views using view templates in Drupal 8 and 9
How to create custom node template file in Drupal 8 and 9 themes