如何将带下拉菜单的HTML菜单转为WordPress动态菜单?
解决WordPress动态菜单匹配原HTML结构的问题
你的代码存在几个核心问题,导致无法生成与原HTML一致的下拉菜单:
- 错误使用菜单项ID调用
wp_get_nav_menu_items(),该函数需要传入菜单ID而非单个菜单项ID,无法正确获取子菜单 - 未处理二级子菜单(原HTML中的
dropdown-submenu结构) - 类名、图标与原HTML不匹配(比如用
dropdown-arrow替代了fa fa-angle-down,子菜单标签类错误) - 未实现
active类的页面匹配逻辑
解决方案:构建层级菜单并递归渲染
首先,我们需要将扁平的菜单数据按父ID分组,再通过递归函数渲染多级菜单,严格匹配原HTML的类和结构:
1. 整理菜单层级数据
<?php $menuLocations = get_nav_menu_locations(); $menuID = $menuLocations['header']; $menuItems = wp_get_nav_menu_items($menuID); // 按父ID分组菜单项,构建层级结构 $menuHierarchy = []; foreach ($menuItems as $item) { $menuHierarchy[$item->menu_item_parent][] = $item; } ?>
2. 编写递归渲染函数
<?php function render_menu_items($items, $menuHierarchy) { $output = ''; foreach ($items as $item) { // 判断是否包含子菜单 $hasChildren = isset($menuHierarchy[$item->ID]); // 判断当前菜单项是否为活跃状态 $isActive = (get_permalink() === $item->url) || (is_post_type_archive($item->object) && $item->type === 'post_type_archive'); // 拼接li标签类名 $liClass = 'nav-item'; if ($hasChildren) $liClass .= ' dropdown'; if ($isActive) $liClass .= ' active'; $output .= '<li class="' . esc_attr($liClass) . '">'; // 拼接a标签类名和属性 $aClass = 'nav-link'; $aAttrs = 'href="' . esc_url($item->url) . '" title="' . esc_attr($item->title) . '"'; if ($hasChildren) { $aClass .= ' dropdown-toggle'; $aAttrs .= ' data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"'; } $output .= '<a class="' . esc_attr($aClass) . '" ' . $aAttrs . '>'; $output .= esc_html($item->title); // 添加原HTML的下拉箭头图标 if ($hasChildren) $output .= ' <i class="fa fa-angle-down"></i>'; $output .= '</a>'; // 渲染子菜单 if ($hasChildren) { $subMenuClass = 'dropdown-menu'; // 二级子菜单的父项需要添加dropdown-submenu类 if ($item->menu_item_parent !== 0) { $output .= '<li class="dropdown-submenu">'; } $output .= '<ul class="' . esc_attr($subMenuClass) . '" role="menu">'; $output .= render_menu_items($menuHierarchy[$item->ID], $menuHierarchy); $output .= '</ul>'; if ($item->menu_item_parent !== 0) { $output .= '</li>'; } } $output .= '</li>'; } return $output; } ?>
3. 在模板中调用渲染函数
<nav class="navbar navbar-expand-lg navbar-dark p-0"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbar-collapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div id="navbar-collapse" class="collapse navbar-collapse"> <?php // 渲染顶级菜单项 if (!empty($menuHierarchy[0])) { echo '<ul class="nav navbar-nav mr-auto">'; echo render_menu_items($menuHierarchy[0], $menuHierarchy); echo '</ul>'; } ?> </div> </nav>
关键细节说明
- 层级分组:通过
menu_item_parent将菜单项分组,解决原代码无法正确获取子菜单的问题 - 递归渲染:自动处理多级子菜单,完美匹配原HTML的
dropdown-submenu结构 - 类名严格匹配:所有CSS类(如
nav-item dropdown、dropdown-submenu)与原HTML完全一致 - 活跃状态判断:通过对比当前页面链接和菜单项URL,自动添加
active类 - 图标还原:使用原HTML的
fa fa-angle-down图标替代自定义箭头
内容的提问来源于stack exchange,提问作者Amir Sandila
相关产品推荐
相关产品推荐

