2

In hook_preprocess_menu(), I want to add custom classes to the <li> tag.

I tried the following lines of code, one at a time.

  • $item['attributes']->addClass('section');
  • $item['attributes']->setAttribute('class', array('section'));
  • $item['attributes']->setAttribute('class', 'section');

In any case, this is the HTML markup I get.

<li class="Array class">

How do I add the desired classes?

2
  • Did you try just adding it in the menu twig file first? – Kevin Dec 31 '18 at 16:42
  • Have you also tried $item['attributes']['class'][] = 'section';? – leymannx Oct 4 '19 at 7:24
2

Assuming your theme extends Classy, you can add a menu.html.twig file in your theme to override the menu twig used:

https://api.drupal.org/api/drupal/core%21themes%21classy%21templates%21navigation%21menu.html.twig/8.6.x

This block here:

{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
  ]
%}

Simply add a new line:

{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    'section'
  ]
%}

If your theme does not use Classy as a base, then you have to refer to the Stable theme twig file which does not do this:

https://api.drupal.org/api/drupal/core%21themes%21stable%21templates%21navigation%21menu.html.twig/8.6.x

In this case, you would have to add the set block within the for item in items loop just like the Classy file does, and add addClass(classes) method on the li item:

{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    'section'
  ]
%}
<li{{ item.attributes.addClass(classes) }}>

This will add the 'section' class on every single li in the menu though, so, if you only want it to apply to the top level menu items for example, you could do:

{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    menu_level == 0 ? 'section'
  ]
%}

Additionally, if you only want this to apply to a particular menu and not all menus, then your Twig file needs to be named menu--MENU_NAME.html.twig. Clear caches to see any changes.

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.