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 %}