You need to enable JavaScript to run this app. 使用wp_get_menu_array()自定义菜单时如何添加当前菜单项激活类
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 03:54:08