I'm using a menu block to output a section of my main menu into a region so I can have a "In This Section" type of sub menu on every page.

Unfortunately, I can't find a way to pinpoint in menu.html.twig which rendition of "main_menu" I am working with. (they both have the same "menu_name") I want to adjust the markup for the menu block, but not for my main menu.

A similar question was asked here: Additional twig suggestions for menus in Drupal 8

I don't quite understand the suggested answer. Is there some way I can extend some class to call a different Twig Template? Is there some hook I'm missing?

  • Just a thought, did you enable Twig debugging so you can see relevant template suggestions? – Danny Englander Mar 5 '16 at 17:30
  • Hi Danny, yeah, I have debugging in place, I can easily target my menu BLOCK with a different Twig template, but I can target my menu block MENU... if that makes any sense. I'm wondering if I can alter the MenuLinkTree service and call a different tpl for a Menu block vs. a regular Menu? – Greg Mar 5 '16 at 20:42
  • I have not attempted what you are doing but I am working on a new theme this weekend so I will take a look and see if I learn anything. Moreover, what is exactly that you are trying to do? Do you wish to alter the markup of the menu block sub-menu? – Danny Englander Mar 5 '16 at 21:12
  • Huh, so how do I get a new menu block? I already have my main menu placed as a block with the levels set. I'm sure I am missing something obvious. – Danny Englander Mar 5 '16 at 21:16
  • I want to alter the markup around the menu ul's and li's for the main menu when it is in my menu block, but not when it's in the header. In menu.html.twig I can only access the menu_name which is the same for both menus so I have no way to target just my menu block's ul's and li's. – Greg Mar 5 '16 at 21:25

Ok, I think I found the answer. Kristian Kaa answers it on his blog here: http://kristiankaa.dk/article/drupal8-region-specific-menu-theme-hook-suggestion

Basically you use 2 preprocess functions like so:

 * Implements hook_preprocess_block().
function mymodule_preprocess_block(&$variables) {
  $variables['content']['#attributes']['block'] =    $variables['attributes']['id'];

 * Implements hook_theme_suggestions_HOOK_alter().
function mymodule_theme_suggestions_menu_alter(array &$suggestions, array $variables) {
  // Remove the block and replace dashes with underscores in the block ID to
  // use for the hook name.
  if (isset($variables['attributes']['block'])) {
    $hook = str_replace(array('block-', '-'), array('', '_'),    $variables['attributes']['block']);
    $suggestions[] = $variables['theme_hook_original'] . '__' . $hook;

This will add the block ID as a new theme hook suggestion. Many thanks to Kristian.

  • For me this results in: Notice: Array to string conversion in mytheme_theme_suggestions_menu_alter() (line 14 of themes/custom/hemet/mytheme.theme). – Benedikt Dec 22 '17 at 9:50

FWIW, I ran into an issue while using Greg's answer where I was getting errors about $variables['attributes']['id'] not having the "id" key. To fix this I added a check to ensure that this key is set.

 * Implements hook_preprocess_block().
 * http://kristiankaa.dk/article/drupal8-region-specific-menu-theme-hook-suggestion
function THEMENAME_preprocess_block(&$variables) {
  if(isset($variables['attributes']['id'])) {
    $variables['content']['#attributes']['block'] = $variables['attributes']['id'];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.