5

Drupal 8 Beta 1 has a lot of nice templates to use which can be brought into a custom theme and then customized. I brought in core's menu.html.twig into my custom theme and indeed I can customize markup in there. However, this template overrides all Drupal menus, not just the primary menu which is the one I want to override.

I tried the Devel module for Drupal 8 figuring I might get some insight about what's going on under the hood. However, the module still looks like it's in a state of flux and I got massive errors. My goto module for template suggestions for Drupal 7 is Devel Themer (Theme Developer) but alas no Drupal 8 version.

I also tried getting specific with the template name and tried menu--primary.html.twig but that did not work either.

I then tried within the template wrapping an if around the part that I want to modify as such:

{% if primary_menu %}
   <ul{{ attributes.addClass('foobar-menu') }}>
{% endif %}

... but no joy there either. so I am out of ideas on how to do this.

11

Answering my own question here, this will probably be useful for those looking to debug twig.

  1. Activate devel Kint (part of the Devel module) on the modules page or with Drush
  2. In your site /sites/default/services.yml change the following settings:

    parameters: twig.config: debug: true cache: false auto_reload: true

  3. Then in the template you want to debug, place this code in it:

    {{ kint() }}

Now you get a nice tree of variables that prints out similar to what you would get if you did an old style kpr(get_defined_vars()); in Drupal 7.

{{ kint() }} printout of vars

  1. I see from the debug printout that the name of the menu is simply main.
  2. Now I change the overridden template in my custom theme's template folder to menu--main.html.twig
  3. Voila, the template is only specific for the primary main menu now
  4. Customize as a themer to your hearts content.
  5. Throughout this process, don't forget to clear cache and change / remove any debug code when you are done.

In addition to this, with debugging active, Chrome prints out possible template suggestions a la devel_themer so you don't necessarily have to use Kint.

enter image description here

  • 1
    As the *depth too great* shows Drupal 8 is not yielding well to these dump-in-the-browser hacks. It's better to use a debugger. – user49 Oct 4 '14 at 16:48
  • @chx - right there were quite a few apache out of memory messages until I got a handle on how to do this but even still the depth too great messages. What would you suggest for a better debugger? Kint comes with Drupal 8 Devel so I am guessing a lot of folks will be using that. – Danny Englander Oct 4 '14 at 17:50
1

Just in case the OP meant the primary menu and not the main menu, we need to remember regions can have any menu assigned to them, or even multiple menus.

So if you're trying to theme whatever menu(s) are placed in specific regions, you need to add a theme hook suggestion. Here's how I did it:

In your .theme or .module file:


use \Drupal\block\Entity\Block;

/**
 * Implements hook_theme_suggestions_HOOK_alter() for block templates.
 */
function TEMPLATE_theme_suggestions_block_alter(array &$suggestions, array $variables) {
  $base_plugin_id = $variables['elements']['#base_plugin_id'];
  $system_menu_block = $base_plugin_id == 'system_menu_block';

  if ($system_menu_block) {
    $id = $variables['elements']['#id'];
    $block = Block::load($id);
    $region = $block->get('region');
    $suggestions[] = 'block__' . $region . '__menu';
  }
}

You now have new theme hook suggestions for all system menu blocks:

TEMPLATE_preprocess_block__REGION__menu()

Use the theme hook suggestions like so:


/**
 * Implements template_preprocess_block() for the primary menu region.
 */
function TEMPLATE_preprocess_block__primary_menu__menu(&$variables) {
  $variables['content']['#theme'] = 'menu__primary';
}

Finally, create the template file using the #theme variable you assigned above:

menu--primary.html.twig

So if you have a sidebar_first region, use:


/**
 * Implements template_preprocess_block() for the sidebar_first region.
 */
function TEMPLATE_preprocess_block__sidebar_first__menu(&$variables) {
  $variables['content']['#theme'] = 'menu__sidebar_first';
}

and:

menu--sidebar-first.html.twig

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.