使用wp_get_menu_array()自定义菜单时如何添加当前菜单项激活类
自定义菜单输出时无法获取当前选中状态类的解决方案
问题根因
你当前使用的简版wp_get_menu_array()自定义函数,没有提取WordPress菜单项原生携带的状态类信息。
WordPress核心在加载菜单项时,会自动根据当前访问页面的上下文,为每个菜单项的classes属性预先计算好你需要的全部状态类:
- 直接匹配当前访问页的菜单项,自动携带
current-menu-item - 包含当前选中子项的上层菜单项,自动携带
current-menu-parent、current-menu-ancestor - 关联页面类型的菜单项,自动携带
current_page_parent、current_page_ancestor
目前网上流传的绝大多数简版wp_get_menu_array()实现,只提取了菜单项的ID、标题、链接、子项关系,完全漏掉了classes字段。你现有模板代码里已经尝试输出$childItem['classes']、$grandChild['active-class']这些字段,但因为函数没有返回对应键值,所以实际渲染时这些位置是空字符串,不会有任何生效的类名。
第一步:修正wp_get_menu_array()函数
替换现有函数实现,确保每个菜单项节点都原生携带系统计算的类名:
function wp_get_menu_array($menu_slug) { $raw_menu_items = wp_get_nav_menu_items($menu_slug); if (empty($raw_menu_items)) return []; $menu_nodes = []; // 遍历所有原始菜单项,存入基础字段 foreach ($raw_menu_items as $item) { $menu_nodes[$item->ID] = [ 'ID' => $item->ID, 'title' => $item->title, 'url' => $item->url, // *关键:把WordPress预计算的全部类名存入节点,包含所有current状态类* 'classes' => $item->classes, 'parent_id' => $item->menu_item_parent, 'children' => [] ]; } // 构建菜单层级关系 foreach ($menu_nodes as $node_id => $node) { if ($node['parent_id'] && isset($menu_nodes[$node['parent_id']])) { $menu_nodes[$node['parent_id']]['children'][$node_id] = &$menu_nodes[$node_id]; } } // 过滤返回顶级菜单节点 return array_values(array_filter($menu_nodes, function($node) { return empty($node['parent_id']); })); }
注意:这里完全不需要手动判断当前页面对应哪个菜单项,WordPress核心已经完成了全部状态判断逻辑,你只需要把现成的类名提取出来即可,避免手动写判断逻辑出现匹配偏差。
第二步:修正模板拼接逻辑
在现有输出代码中,把提取到的状态类正确拼接到对应HTML标签的class属性上:
- 顶级父菜单项的
<li>标签:把节点自带的类和原有样式类合并
原有代码:
修正为:<li id="list-<?= $parentItem['ID']?>" class="<?= $hasChildren;?>" role="listitem"><li id="list-<?= $parentItem['ID']?>" class="<?= $hasChildren . ' ' . implode(' ', $parentItem['classes']);?>" role="listitem" > - 二级子菜单项的
<li>标签:合并节点携带的状态类
原有代码:
修正为:<li class="<?= $hasGrandChildren;?> <?= $childItem['classes'];?>" role="listitem"><li class="<?= $hasGrandChildren . ' ' . implode(' ', $childItem['classes']);?>" role="listitem" > - 三级孙菜单项的
<li>和<a>标签:合并状态类
原有代码:
修正为:<li id="menu-item-<?= $grandChild['ID'];?>" class="navbar-nav__grandchild-list-item <?= $grandChild['classes']?>" role="listitem"> <a href="<?= $grandChild['url'];?>" class="navbar-nav__grandchild-link <?= $grandChild['active-class'];?>"><li id="menu-item-<?= $grandChild['ID'];?>" class="navbar-nav__grandchild-list-item <?= implode(' ', $grandChild['classes'])?>" role="listitem" > <a href="<?= $grandChild['url'];?>" class="navbar-nav__grandchild-link <?= implode(' ', $grandChild['classes'])?>" >
注意事项
- WordPress返回的
classes字段是数组格式,拼接成HTML类名时一定要用implode(' ', $classes)转成字符串,不能直接输出数组 - 不要自行重写当前选中状态的判断逻辑,核心的状态匹配逻辑已经在菜单加载流程中实现,手动写判断很容易出现跨页、层级匹配不准的问题
- 你在WordPress后台菜单编辑界面手动添加的自定义类,也会自动随
classes字段返回,不需要额外处理
内容的提问来源于stack exchange,提问作者RMH
相关产品推荐
相关产品推荐

