Drupal 8 Template naming

Submitted by shiv on Sat, 12/05/2015 - 12:58

Drupal loads templates based on certain naming conventions. This allows you to override templates by adding them to your theme and giving them specific names. After adding a template you must rebuild the cache in order for Drupal to discover your new template. You can debug Twig templates to figure out which templates are being used to output the markup for any given element. This page lists the conventions used for the base html structure, the page, regions, blocks, nodes, fields, and other core components.

HTML (template)

The HTML template provides markup for the basic structure of the HTML-page including the, and tags. Base template: html.html.twig (base location: core/modules/system/templates/html.html.twig) The following are some examples of how you may override the base template:

  1. html--internalviewpath.html.twig
  2. html--node--id.html.twig
  3. html.html.twig

See the html.html.twig API documentation.

Page template

Pattern: page--[front|internal/path].html.twig Base template: page.html.twig (base location: core/modules/system/templates/page.html.twig) The suggestions are numerous.

The front page takes precedence. The rest are based on the internal path of the current page. The front page can be set at "Administration > Configuration > System > Site information." (http://example.com/admin/config/system/site-information). The front page template is page--front.html.twig.

Do not confuse the internal path with path aliases, which are not accounted for. The list of suggested template files is in order of specificity based on internal paths. One suggestion is made for every element of the current path, though numeric elements are not carried to subsequent suggestions. For example, "http://www.example.com/node/1/edit" would result in the following suggestions:

  1. page--node--edit.html.twig
  2. page--node--1.html.twig
  3. page--node.html.twig
  4. page.html.twig

See the page.html.twig API documentation. Also see below for the maintenance page template.

How to add in Drupal 8 a custom (suggestion) page template based on content types 

To do that in our (custom) theme folder in the .theme file we have to add the following hook function: hook_theme_suggestions_HOOK_alter like below:

 

<?php
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function THEME_NAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {

  if ($node = \Drupal::routeMatch()->getParameter('node')) {
    $content_type = $node->bundle();
    $suggestions[] = 'page__'.$content_type;
  }
}
?>

A different method, however the main difference with my code is that I use array_splice to place the suggestion one above page--node, this preserves the capability to override with page--node--% and page--node--[id]. Your suggestion will always take precedence because you have pushed it onto the array.

If I put them both in you can see this in the suggestions list:

  1. page--node
  2. page--node--page (my method)
  3. page--node--%
  4. page--node--24
  5. page--page (your method)
function THEME_NAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  // Add content type suggestions.
  if ($node = \Drupal::request()->attributes->get('node')) {
    array_splice($suggestions, 1, 0, 'page__node__' . $node->getType());
  }
}

Regions

Pattern: region--[region].html.twig Base template: region.html.twig (base location: core/modules/system/templates/region.html.twig) The region template is used when a page region has content, either from the Block system or a function like hook_page_build(). Possible region names are determined by the theme's .info.yml file. See the region.html.twig API documentation.

Blocks

Pattern: block--[module|-delta]].html.twig Base template: block.html.twig (base location: core/modules/block/templates/block.html.twig)

  1. block--module--delta.html.twig
  2. block--module.html.twig
  3. block--system-branding-block.html
  4. block.html.twig

"module" being the name of the module and "delta", the internal id assigned to the block by the module. For example, "block--block--1.html.twig" would be used for the first user-submitted block added from the block administration screen since it was created by the block module with the id of 1. Region-specific block templates are not available in Drupal 8. If you had a block created by a custom module called "custom" and a delta of "my-block", the theme hook suggestion would be called "block--custom--my-block.html.twig." Also one more example with Views, if you have a block created by views with a view name "front_news" and display id "block_1" then the theme hook suggestion would be: block--views-block--front-news-block-1.html.twig (notice, when you have underscores in a display id or in a view name - you have to transform them in to a single dash) Be aware that module names are case sensitive in this context. For instance if your module is called 'MyModule', the most general theme hook suggestion for this module would be "block--MyModule.html.twig." See the block.html.twig API documentation

"Block Type" like 'content type' template.

use this function in ThemeName.theme file.-

/**

 * Implements hook_theme_suggestions_HOOK_alter() for form templates.

 */

function beginning_theme_suggestions_block_alter(array &$suggestions, array $variables) {

  $block = $variables['elements'];

  $blockType = $block['#configuration']['provider'];

  

  if ($blockType == "block_content") {

    $bundle = $block['content']['#block_content']->bundle();

    $suggestions[] = 'block__' . $bundle;

  }

}

After creating this function in .theme file create "Block Type" through Drupal 8's interface through this link admin/structure/block/block-content/types and http://localhost/drupal/1Drupal8Doc/admin/structure/block/block-content/types/add while creating "Block Type" take care of using name without space. Machine name should be without space.

Nodes

Pattern: node--[type|nodeid]--[viewmode].html.twig Base template: node.html.twig (base location: core/modules/node/templates/node.html.twig) Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds:

  1. node--nodeid--viewmode.html.twig
  2. node--nodeid.html.twig
  3. node--type--viewmode.html.twig
  4. node--type.html.twig
    For example node--article.html.twig
  5. node--viewmode.html.twig
  6. node.html.twig

Note that underscores in a content type's machine name are replaced by hyphens. See the node.html.twig API documentation..

Taxonomy terms

Pattern: taxonomy-term--[vocabulary-machine-name|tid].html.twig Base template: taxonomy-term.html.twig (base location: core/modules/taxonomy/templates/taxonomy-term.html.twig) Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds:

  1. taxonomy-term--tid.html.twig
  2. taxonomy-term--vocabulary-machine-name.html.twig
  3. taxonomy-term.html.twig

Note that underscores in a vocabulary's machine name are replaced by hyphens. See the taxonomy-term.html.twig API documentation.

Fields

Pattern: field--[type|name[--content-type]|content-type].html.twig Base template: field.html.twig (base location: core/modules/system/templates/field.html.twig) Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds:

  1. field--field-name--content-type.html.twig
  2. field--content-type.html.twig
  3. field--field-name.html.twig
  4. field--field-type.html.twig
  5. field.html.twig

Note that underscores in a Field's machine name are replaced by hyphens. Also remember to include "field-" in custom field names, e.g: field--field-phone.html.twig. See the field.html.twig API documentation.

Comments

Pattern: comment--node-[type].html.twig Base template: comment.html.twig (base location: core/modules/comment/template/comment.html.twig) Support was added to create comment--node-type.html.twig files, to format comments of a certain node type differently than other comments in the site. For example, a comment made on an article-type node would be "comment--node-article.html.twig". See the comment.html.twig API documentation.

Comment wrappers

Pattern: comment-wrapper--node-[type].html.twig Base template: comment-wrapper.html.twig Similar to the above but for the wrapper template.

Forums

Pattern: forums--[[container|topic]--forumID].html.twig Base template: forums.html.twig (base location: core/modules/forum/templates/forums.html.twig) Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds: For forum containers:

  1. forums--containers--forumID.html.twig
  2. forums--forumID.html.twig
  3. forums--containers.html.twig
  4. forums.html.twig

For forum topics:

  1. forums--topics--forumID.html.twig
  2. forums--forumID.html.twig
  3. forums--topics.html.twig
  4. forums.html.twig

See the API documentation for forums.html.twig.

Maintenance page

Pattern: maintenance-page--[offline].html.twig Base template: maintenance-page.html.twig (base location: core/modules/system/templates/maintenance-page.html.twig) This applies when the database fails. Useful for presenting a friendlier page without error messages. Theming the maintenance page must be properly setup first. See the maintenance-page.html.twig API documentation.

Search result

Pattern: search-result--[searchType].html.twig Base template: search-result.html.twig (base location: core/modules/search/templates/search-result.html.twig) search-result.html.twig is the default wrapper for individual search results. Depending on type of search different suggestions are made. For example, "example.com/search/node/Search+Term" would result in "search-result--node.html.twig" being used. Compare that with "example.com/search/user/bob" resulting in "search-result--user.html.twig". Modules can extend search types adding more suggestions of their type. See the search-result.html.twig API documentation.

Read More

Views template files

The default style for all views is views-view-unformatted.html.twig.

Many styles will then farm out the actual display of each row to a row style; the default row style is views-view-fields.html.twig.

Here is an example of all the templates that will be tried in the following case:

View, named foobar. Style: unformatted. Row style: Fields. Display: Page.

  • views-view--foobar--page.html.twig
  • views-view--page.html.twig
  • views-view--foobar.html.twig
  • views-view.html.twig
  • views-view-unformatted--foobar--page.html.twig
  • views-view-unformatted--page.html.twig
  • views-view-unformatted--foobar.html.twig
  • views-view-unformatted.html.twig
  • views-view-fields--foobar--page.html.twig
  • views-view-fields--page.html.twig
  • views-view-fields--foobar.html.twig
  • views-view-fields.html.twig

Important! When adding a new template to your theme, be sure to flush the theme registry cache!

See also

views-view.html.twig

Available variables:

  • attributes: Remaining HTML attributes for the element.
  • css_name: A css-safe version of the view name.
  • css_class: The user-specified classes names, if any.
  • header: The optional header.
  • footer: The optional footer.
  • rows: The results of the view query, if any.
  • empty: The content to display if there are no rows.
  • pager: The optional pager next/prev links to display.
  • exposed: Exposed widget form/info to display.
  • feed_icons: Optional feed icons to display.
  • more: An optional link to the next page of results.
  • title: Title of the view, only used when displaying in the admin preview.
  • title_prefix: Additional output populated by modules, intended to be displayed in front of the view title.
  • title_suffix: Additional output populated by modules, intended to be displayed after the view title.
  • attachment_before: An optional attachment view to be displayed before the view content.
  • attachment_after: An optional attachment view to be displayed after the view content.
  • dom_id: Unique id for every view being printed to give unique class for Javascript.
  1. {#
  2. /**
  3. * @file
  4. * Default theme implementation for main view template.
  5. *
  6. * Available variables:
  7. * - attributes: Remaining HTML attributes for the element.
  8. * - css_name: A css-safe version of the view name.
  9. * - css_class: The user-specified classes names, if any.
  10. * - header: The optional header.
  11. * - footer: The optional footer.
  12. * - rows: The results of the view query, if any.
  13. * - empty: The content to display if there are no rows.
  14. * - pager: The optional pager next/prev links to display.
  15. * - exposed: Exposed widget form/info to display.
  16. * - feed_icons: Optional feed icons to display.
  17. * - more: An optional link to the next page of results.
  18. * - title: Title of the view, only used when displaying in the admin preview.
  19. * - title_prefix: Additional output populated by modules, intended to be
  20. * displayed in front of the view title.
  21. * - title_suffix: Additional output populated by modules, intended to be
  22. * displayed after the view title.
  23. * - attachment_before: An optional attachment view to be displayed before the
  24. * view content.
  25. * - attachment_after: An optional attachment view to be displayed after the
  26. * view content.
  27. * - dom_id: Unique id for every view being printed to give unique class for
  28. * Javascript.
  29. *
  30. * @see template_preprocess_views_view()
  31. *
  32. * @ingroup themeable
  33. */
  34. #}
  35. {%
  36. set classes = [
  37. dom_id ? 'js-view-dom-id-' ~ dom_id,
  38. ]
  39. %}
  40. <div{{ attributes.addClass(classes) }}>
  41. {{ title_prefix }}
  42. {{ title }}
  43. {{ title_suffix }}
  44.  
  45. {% if header %}
  46. <header>
  47. {{ header }}
  48. </header>
  49. {% endif %}
  50.  
  51. {{ exposed }}
  52. {{ attachment_before }}
  53.  
  54. {{ rows }}
  55. {{ empty }}
  56. {{ pager }}
  57.  
  58. {{ attachment_after }}
  59. {{ more }}
  60.  
  61. {% if footer %}
  62. <footer>
  63. {{ footer }}
  64. </footer>
  65. {% endif %}
  66.  
  67. {{ feed_icons }}
  68. </div>

 

Sample blackbox block

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas non porta odio, id mattis erat.

Nam sed tincidunt eros. Donec a venenatis odio, vitae commodo sem. Vivamus ullamcorper pellentesque erat, in adipiscing tortor scelerisque sit amet. Nulla pulvinar urna magna. Vivamus a ipsum lorem. Etiam adipiscing pulvinar lorem.