Customize Drupal templates with twig template suggestions. Here is the list of twig template suggestions for various Drupal entities including view modes.
So here is an article that gives you the snippets to get theme suggestions for all Drupal concepts. On your themeName.theme file add the following hook functions to get the twig suggestions based on the requirement
Content type
Page level suggestions
<?php
/**
* Implements hook_theme_suggestions_page_alter().
*/
function themeName_theme_suggestions_page_alter(array &$suggestions, array $variables) {
if ($node = \Drupal::routeMatch()->getParameter('node')) {
$suggestions[] = 'page__' . $node->bundle();
}
}
Node level suggestions
<?php
/**
* Implements hook_theme_suggestions_node_alter().
*/
function themeName_theme_suggestions_node_alter(array &$suggestions, array $variables) {
if ($node = \Drupal::routeMatch()->getParameter('node')) {
$suggestions[] = 'node__' . $node->bundle();
}
}
/*If we want to show the twig suggestions only for authenticated users, then here is the hook function*/
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function themeName_theme_suggestions_node_alter(array &$suggestions, array $variables) {
$logged_in = \Drupal::currentUser()->isAuthenticated();
if ($logged_in) {
$suggestions[] = 'node__' . 'authenticated';
}
}
Block type
Suggestions for custom block type
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter() for block templates.
*/
function themeName_theme_suggestions_block_alter(&$suggestions, $variables) {
$content = $variables['elements']['content'];
if (isset($content['#block_content']) && $content['#block_content'] instanceof \Drupal\block_content\BlockContentInterface) {
$suggestions[] = 'block__' . $content['#block_content']->bundle();
}
}
Suggestions for custom block types based on the region
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter() for block templates based on regions.
*/
function themeName_theme_suggestions_block_alter(&$suggestions, $variables) {
// Region suggestion for blocks in panels.
if (isset($variables['elements']['#configuration']['region'])) {
$region = $variables['elements']['#configuration']['region'];
$suggestions[] = 'block__' . $region;
if (isset($variables['elements']['#configuration']['provider'])) {
$provider = $variables['elements']['#configuration']['provider'];
$suggestions[] = 'block__' . $region . '__' . $provider;
}
}
// Region suggestion for blocks in Drupal.
if (isset($variables['elements']['#id'])) {
if ($block = Block::load($variables["elements"]["#id"])) {
$region = $block->getRegion();
$suggestions[] = 'block__' . $region;
$suggestions[] = 'block__' . $region . '__' . $variables['elements']['#base_plugin_id'];
$suggestions[] = 'block__' . $region . '__' . $variables['elements']['#id'];
$suggestions[] = 'block__' . $region . '__' . $variables['elements']['#base_plugin_id'] . '__' . $variables['elements']['#id'];
}
}
}
Suggestions for custom block types based on view mode
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter() for block templates.
*/
function themeName_theme_suggestions_block_alter(&$suggestions, $variables) {
// View mode suggestion for custom blocks.
if (isset($variables['elements']['#configuration']['view_mode'])) {
$view_mode = $variables['elements']['#configuration']['view_mode'];
$suggestions[] = 'block__' . $view_mode;
}
else {
$view_mode = NULL;
}
// Custom Blocks (Bundles and view mode).
if ($variables['elements']['#base_plugin_id'] === 'block_content'
&& isset($variables['elements']['content']['#block_content'])) {
// Bundle type.
$bundle = $variables['elements']['content']['#block_content']->bundle();
$suggestions[] = 'block__' . $region . '__' . $bundle;
if ($view_mode = $variables['elements']['content']['#view_mode']) {
$suggestions[] = 'block__' . $region . '__' . $bundle . '__' . $view_mode;
$suggestions[] = 'block__' . $bundle . '__' . $view_mode;
}
$suggestions[] = 'block__' . $bundle;
}
}
Menus
<?php
use Drupal\block\Entity\Block;
/**
* Implements hook_preprocess_HOOK().
*
* Pass block region value to content so this can be used in
* MYTHEME_theme_suggestions_menu_alter.
*/
function themeName_preprocess_block(&$variables) {
if (isset($variables['elements']['#id'])) {
$region = Block::load($variables['elements']['#id'])->getRegion();
$variables['content']['#attributes']['region'] = $region;
}
}
/**
* Implements hook_theme_suggestions_HOOK_alter().
*
* Provide region-based menu suggestions.
*/
function themeName_theme_suggestions_menu_alter(&$suggestions, array $variables) {
if (isset($variables['attributes']['region'])) {
$suggestions[] = 'menu__' . $variables['menu_name'] . '__' . $variables['attributes']['region'];
}
}
Taxonomy vocabulary
<?php
use Drupal\taxonomy\Entity\Term;
/*
* Implements hook_theme_suggestions_HOOK_alter()
* suggestions based term vocabulary id
*/
function THEME_NAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
$term = Term::load($tid);
$suggestions[] = 'page__taxonomy__' . $term->getVocabularyId();
}
}
Taxonomy terms
Suggestions for Taxonomy Terms for Drupal 8
<?php
use Drupal\taxonomy\Entity\Term;
/*
* Implements hook_theme_suggestions_HOOK_alter()
*/
function THEME_NAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
$term = Term::load($tid);
$suggestions[] = 'page__taxonomy__' . $term->getVocabularyId();
}
}
Suggestions for Taxonomy Terms for Drupal 9
Views
Suggestions based on view name
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function themeName_theme_suggestions_views_view_alter(array &$suggestions, array $variables) {
if (isset($variables['view'])) {
$suggestions[] = 'views_view__' . $variables['view']->id();
}
}
Suggestions based on view name followed by its display name
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function themeName_theme_suggestions_views_view_alter(array &$suggestions, array $variables) {
// Check if the current view has a display.
if (!empty($variables['view']->current_display)) {
// Get the view name.
$view_name = $variables['view']->storage->id();
// Get the display machine name.
$display_id = $variables['view']->current_display;
// Add theme suggestions based on view name and display machine name.
$suggestions[] = 'views_view__' . $view_name . '__' . $display_id;
$suggestions[] = 'views_view__' . $view_name;
}
}
In case if the above function doesn’t work, here is the default structure
- views-view-field--[viewid]--[view-display-id]--[fieldid].html.twig
- views-view-field--[viewid]--page--[fieldid].html.twig
- views-view-field--block--[fieldid].html.twig
- views-view-field--[fieldid].html.twig
- views-view-field.html.twig
User
<?php
/**
* Implements hook_theme_suggestions_user_alter().
*/
function themeName_theme_suggestions_user_alter(array &$suggestions, array $variables) {
if ($view_mode = $variables['elements']['#view_mode']) {
$suggestions[] = 'user__' . $view_mode;
}
}
Paragraphs
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function themeName_theme_suggestions_paragraph_alter(&$suggestions, $variables) {
$paragraph = $variables['elements']['#paragraph'];
$parent = $paragraph->getParentEntity();
if ($parent) {
$suggestions[] = 'paragraph__' . $parent->bundle() . '__' . $paragraph->bundle();
}
}
Regions
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
// add a template suggestion based on region name
function themeName_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
if (isset($variables["attributes"]["region"])) {
$suggestions[] = $variables["theme_hook_original"] . "__" . $variables["attributes"]["region"];
}
}
Suggestions for Fields
<?php
/**
* Implements hook_theme_suggestions_field_alter().
*/
function themeName_theme_suggestions_field_alter(array &$suggestions, array $variables) {
$name = $variables['element']['#field_name'];
// View mode.
if ($view_mode = $variables['element']['#view_mode']) {
$suggestions[] = 'field__' . $view_mode;
$suggestions[] = 'field__' . $view_mode . '__' . $name;
}
}
Suggestions for Form Templates
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter() for form templates.
*/
function themeName_theme_suggestions_form_alter(array &$suggestions, array $variables) {
if ($variables['element']['#form_id'] == ‘form_id’) {
$suggestions[] = ‘form_id’;
}
}
Suggestions for Form Elements
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter() for form_element.
*/
function themeName_theme_suggestions_form_element_alter(&$suggestions, $variables) {
if (!empty($variables['element']['#type'])) {
$suggestions[] = 'form_element__' . $variables['element']['#type'];
}
}
Suggestions for views Exposed Form Filters
<?php
/**
* Implements hook_theme_suggestions_views_exposed_form_alter().
*/
function themName_theme_suggestions_views_exposed_form_alter(array &$suggestions, array $variables) {
if (isset($variables['form']['#theme'])) {
// Add all views exposed theme function except base one.
array_pop($variables['form']['#theme']);
$suggestions = $variables['form']['#theme'] + $suggestions;
}
}
Suggestions to override the page title block
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function themename_theme_suggestions_page_title_alter(array &$suggestions, array $variables) {
$suggestions[] = 'page_title__custom';
}
Comment type
Template structure could be in this method for comment types.
comment--field-name-of-the-comment-field-in-the-content-type--content-type.html.twig
comment--field-name-of-the-comment-field-in-the-content-type.html.twig
Comments