1

On a Drupal 8 installation, I have a menu in the sidebar first region. I want to add classes to bootstrap classes to the different levels of that menu. For that I created a my own menu template, which looks like this:

{#
/**
 * @file
 * Theme override to display a menu.
 */
#}

{% import _self as menus %}

{{ menus.menu_links(items, attributes, 0, my_menu) }} {# 1. #}

{% macro menu_links(items, attributes, menu_level, my_menu) %} {# 1. #}
    {% import _self as menus %}
    {# 1. #}
    {%
    set menu_classes = [
    'navbar-nav', 'mr-auto' ~ my_menu|clean_class,
    ]
    %}
    {# 1. #}
    {%
    set submenu_classes = [
    'navbar-nav', 'mr-auto' ~ my_menu|clean_class,
    ]
    %}
    {% if items %}
        {% if menu_level == 0 %}
            <div class="navbar-collapse offcanvas-collapse open"><ul{{ attributes.addClass(menu_classes) }}> {# 1. #}
        {% else %}
            <ul{{ attributes.removeClass(menu_classes).addClass(submenu_classes) }}> {# 1. #}
        {% endif %}
        {% for item in items %}
            {# 1. #}
            {%
            set item_classes = [
            'nav-item' ~ my_menu|clean_class,
            item.is_expanded ? 'expanded' ~ my_menu|clean_class,
            item.is_collapsed ? 'collapsed' ~ my_menu|clean_class,
            item.in_active_trail ? 'trail' ~ my_menu|clean_class,
            ]
            %}
            {# 1. #}
            {%
            set link_classes = [
            'nav-link' ~ my_menu|clean_class,
            ]
            %}
            <li{{ item.attributes.addClass(item_classes) }}>{# 1. #}
                {# 1. #}
                {{
                link(
                item.title,
                item.url,
                item.attributes.removeClass(item_classes).addClass(link_classes)
                )
                }}
                {% if item.below %}
                    {{ menus.menu_links(item.below, attributes, menu_level + 1, my_menu) }} {# 1. #}
                {% endif %}
            </li>
        {% endfor %}
        {% if menu_level == 0 %}
            </ul></div>
        {% else %}
            </ul>
        {% endif %}

    {% endif %}
{% endmacro %}

This works fine. However, I also need to change the classes of the nav tag. I can't seem to figure out, how that can be done and I can't find any information anywhere explaining this. So how do I change the nav tag classes of that menu?

In the end I want it to be a bootstrap offcanvas menu like this one: https://getbootstrap.com/docs/4.0/examples/offcanvas/

But I just can't seem to change the nav tag classes, since I don't know how.

1 Answer 1

0

You'll need to enable Twig template debugging output to do this. Once you do that you should see a number of template suggestions upward in the DOM for the <nav> tag. For example:

   * block--mainnavigation.html.twig
   * block--system-menu-block--main.html.twig
   * block--system-menu-block.html.twig
   * block--system.html.twig
   x block.html.twig

(Note this assumes you are using Drupal's block system to render the menu.) Above are a number of suggestions. If I look in a likely candidate from above, for example, block--system-menu-block.html.twig, I see markup like this:

<nav role="navigation" aria-labelledby="{{ heading_id }}"{{ attributes|without('role', 'aria-labelledby') }}>

You can grab any of these templates from core and then override by using a copy of the template in your theme and then alter the markup per your requirements.

If you are using Twig Tweak to render the menu, then in that case, you can just add your own custom <nav> tag like so, usually in a page template such as page.html.twig:

  <nav role="navigation" aria-labelledby="off-canvas-menu" class="main-menu" id="off-canvas-menu">
    {{ drupal_menu('main', 1, 4, TRUE) }}
  </nav>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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