3

In Drupal 8, how can I render a menu links children without checking 'expanded' on the menu link? I am building a drop down that displays on hover, the links need to render.

My code so far:

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    <ul>
    {% for item in items %}
      {% if menu_level == 0 %}
        {%
          set classes = [
            'global-top__utility-item',
            'js-utility-item',
            item.in_active_trail ? 'active-trail',
            item.below ? 'has-submenu'
          ]
        %}
      {% endif %}
      <li{{ item.attributes.addClass(classes) }}>
        {{ link(item.title, item.url) }}
        {% if item.below %}
          {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
        {% endif %}
      </li>
    {% endfor %}
    </ul>
  {% endif %}
{% endmacro %}

When a parent link has children, they are not rendering unless 'expanded' is checked, which breaks the menu.

3
  • Just load them up and render them I guess, but that's pretty much what the expanded setting does anyway so without changing something else you'll probably end up with the same result. What do you mean by breaks the menu?
    – Clive
    Oct 13, 2016 at 15:02
  • The menu stops rendering at the first parent with the child, unless I uncheck show as expanded
    – Kevin
    Oct 13, 2016 at 15:04
  • I solved it... Answer to come.
    – Kevin
    Oct 13, 2016 at 20:27

1 Answer 1

1

I was able to do this by adding a macro for children below the main one in my template.

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    <ul>
      {% for item in items %}
        {%
          set classes = [
            'global-top__utility-item',
            'js-utility-item',
            item.in_active_trail ? 'active-trail',
            item.below ? 'has-submenu'
          ]
        %}
        <li{{ item.attributes.addClass(classes) }}>
          {% if item.url.options.attributes['data-icon'] is defined and item.url.options.attributes['data-icon'] is not empty %}
            <svg class="icon"><use xlink:href="/themes/custom/pncb/build/img/svg-sprite.svg#{{ item.url.options.attributes['data-icon'] }}"></use></svg>
          {% endif %}

          {{ link(item.title, item.url) }}
          {% if item.below %}
            {{ menus.submenu_links(item.below, attributes, menu_level + 1) }}
          {% endif %}
        </li>
      {% endfor %}
    </ul>
  {% endif %}
{% endmacro %}




{% macro submenu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  <div class="global-top__submenu">
    {% for chunk in items|batch(7) %}
      <ul class="global-top__submenu-col">
        {% for item in chunk %}
          <li{{ item.attributes.addClass(classes) }}>
            {{ link(item.title, item.url) }}
          </li>
        {% endfor %}
      </ul>
    {% endfor %}
  </div>
{% endmacro %}

I split this out due to scoping, different markup for sub menu, and I needed to use the batch filter. Works great.

Your Answer

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

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