Im trying to use bootstrap for an accordion menu. My issue is that I need unique ID’s for each accordion item. I found some similar topics here: Add Unique ID to Menu Item and here: How to add a custom variable that can be accessed on bootstrap's menu–account.html.twig?
Id like to know how I can get a unique ID for each item. Preferably an ID I can store within a variable which I can then pass to the data target attribute. As you can see in my code below, I’m trying to achieve something like that. The issue is that I cannot use the variable in a twig template that I declared within the preprocess function. Help me understand what I’m doing wrong.
Here is my code in my .theme file:
function my_theme_preprocess_menu__main(array &$variables) { $id = 0; foreach ($variables['items'] as $key => $item) { $variables['items'][$key]['accordionNav']=[]; $key_hash = hash('crc32b', $key); $variables['items'][$key]['accordionNav'] = $key_hash ; } }
Here is my twig file menu–main.html.twig:
{% import _self as menus %} {# We call a macro which calls itself to render the full tree. @see http://twig.sensiolabs.org/doc/tags/macro.html #} {{ menus.menu_links(items, attributes, 0) }} {% macro menu_links(items, attributes, menu_level) %} {% import _self as menus %} {% if items %} {% if menu_level == 0 %} <ul{{ attributes.addClass('nav navbar-nav').setAttribute('id', 'accordion') }}> {% else %} <ul class="sub-menu card-body"> {% endif %} {% for item in items %} {% set classes = [ menu_level ? 'sub-item' : 'nav-item', item.in_active_trail ? 'active', item.below ? 'card', ] %} <li{{ item.attributes.addClass(classes) }}> {% set link_classes = [ not menu_level ? 'nav-link', item.in_active_trail ? 'active', item.url.getOption('attributes').class ? item.url.getOption('attributes').class | join(' '), 'nav-link-' ~ item.url.toString() | clean_class, ] %} {% if item.below %} {% if item.in_active_trail %} <div class="card-header" id="heading{{ip}}"> <button class="btn btn-link" data-toggle="collapse" data-target="{{accordionNav}}" aria-expanded="true" aria-controls="collapse{{ip}}"> {{ item.title }} </button> </div> <div id="collapse{{ip}}" class="collapse show" aria-labelledby="heading{{ip}}" data-parent="#accordion"> {{ menus.menu_links(item.below, attributes, menu_level + 1) }} {% else %} <div class="card-header" id="heading{{ip}}"> <button class="btn btn-link" data-toggle="collapse" data-target="{{accordionNav}}" aria-expanded="false" aria-controls="collapse{{ip}}"> {{ item.title }} </button> </div> <div id="collapse{{ip}}" class="collapse" aria-labelledby="heading{{ip}}" data-parent="#accordion"> {{ menus.menu_links(item.below, attributes, menu_level + 1) }} {% endif %} </div> {% else %} {{ link(item.title, item.url, {'class': link_classes}) }} {% endif %} </li> {% endfor %} </ul> {% endif %} {% endmacro %}