如何将Drupal 8现有下拉菜单代码改为Bootstrap手风琴菜单?
我来帮你把现有的Drupal菜单模板改成和Bootstrap文档一致的卡片式手风琴结构!咱们一步步调整模板代码,替换掉原来的下拉菜单逻辑,改成手风琴的折叠交互。
首先,先看修改后的完整模板代码,之后我会拆解每个关键修改点:
{# /** * @file * Default theme implementation to display a menu as Bootstrap accordion. * * Available variables: * - menu_name: The machine name of the menu. * - items: A nested list of menu items. Each menu item contains: * - attributes: HTML attributes for the menu item. * - below: The menu item child items. * - title: The menu link title. * - url: The menu link url, instance of \Drupal\Core\Url * - localized_options: Menu link localized options. * - is_expanded: TRUE if the link has visible children within the current * menu tree. * - is_collapsed: TRUE if the link has children within the current menu tree * that are not currently visible. * - in_active_trail: TRUE if the link is in the active trail. * * @ingroup templates */ #} {% import _self as menus %} {# Render the full accordion tree #} {{ menus.menu_links(items, attributes, 0) }} {% macro menu_links(items, attributes, menu_level) %} {% import _self as menus %} {% if items %} {# Top level: Bootstrap accordion container #} {% if menu_level == 0 %} <div class="accordion" id="accordion-{{ menu_name }}"> {% endif %} {% for item in items %} {% set collapse_id = 'collapse-' ~ menu_name ~ '-' ~ menu_level ~ '-' ~ loop.index %} {% set is_active = item.in_active_trail ? 'show' : '' %} {# For items with children: Build accordion card #} {% if item.below %} <div class="card"> <div class="card-header" id="heading-{{ collapse_id }}"> <h2 class="mb-0"> <button class="btn btn-link {% if item.in_active_trail %}active{% endif %}" type="button" data-toggle="collapse" data-target="#{{ collapse_id }}" aria-expanded="{{ item.in_active_trail ? 'true' : 'false' }}" aria-controls="{{ collapse_id }}" > {{ item.title }} </button> </h2> </div> <div id="{{ collapse_id }}" class="collapse {{ is_active }}" aria-labelledby="heading-{{ collapse_id }}" data-parent="#accordion-{{ menu_name }}" > <div class="card-body"> {# Render child menu items as a list #} <ul class="list-unstyled"> {{ menus.menu_links(item.below, attributes, menu_level + 1) }} </ul> </div> </div> </div> {% else %} {# For items without children: Simple card with link #} <div class="card"> <div class="card-body"> {{ link(item.title, item.url, {'class': ['btn btn-link']}) }} </div> </div> {% endif %} {% endfor %} {# Close top level accordion container #} {% if menu_level == 0 %} </div> {% endif %} {% endif %} {% endmacro %}
关键修改点说明:
顶层容器替换:
原来顶层的<ul>被替换成Bootstrap手风琴的核心容器<div class="accordion">,并且用menu_name生成唯一的ID(id="accordion-{{ menu_name }}"),确保多个菜单不会冲突。手风琴卡片结构:
每个带有子菜单的项(item.below存在)被包装成.card结构,包含:.card-header:手风琴的标题栏,里面是触发折叠的按钮.collapse:存放子菜单的折叠容器,通过data-parent关联顶层手风琴容器,实现“一次只展开一个”的效果
唯一ID生成:
用menu_name + menu_level + loop.index生成唯一的collapse_id,确保每个折叠面板的ID不重复,触发按钮的data-target和折叠面板的id一一对应。激活状态处理:
如果菜单项在当前激活路径(item.in_active_trail为true),自动给折叠面板添加show类,默认展开;同时给触发按钮添加active类,标记为当前激活状态。无子项的菜单项:
没有子菜单的项被做成简单的卡片链接,保持视觉风格统一。移除下拉菜单逻辑:
完全去掉了原来的dropdown类、data-toggle="dropdown"等属性,替换为Bootstrap折叠组件的data-toggle="collapse"等相关属性。
这样修改后,你的Drupal菜单就会输出和Bootstrap文档一致的卡片式手风琴效果啦!如果需要调整样式,比如按钮的颜色、卡片的间距,可以通过自定义CSS来修改。
内容的提问来源于stack exchange,提问作者Sina

