WordPress自定义菜单:父元素与子元素分属不同下拉框
实现父级/子级分离的WordPress下拉菜单
看起来你已经迈出了用Walker定制导航菜单的第一步,但目前的代码还没区分父级和子级菜单元素。我来帮你完善这个Walker,实现把父级菜单放到一个select、子级放到另一个select的需求:
完整的Walker代码
class My_Walker_Nav_Menu_Language extends Walker_Nav_Menu { // 分别存储父级和子级菜单项的数组 private $parent_items = []; private $child_items = []; function start_el(&$output, $item, $depth, $args) { $url = '#' !== $item->url ? esc_url($item->url) : ''; $title = esc_html($item->title); // 根据菜单深度区分父级(depth=0)和子级(depth>=1) if ($depth === 0) { $this->parent_items[] = sprintf('<option value="%s">%s</option>', $url, $title); } else { // 给子级加上父级标题前缀,方便用户识别归属关系 $parent_title = get_the_title($item->menu_item_parent); $child_title = sprintf('%s - %s', esc_html($parent_title), $title); $this->child_items[] = sprintf('<option value="%s">%s</option>', $url, $child_title); } } // 不需要处理层级结束标签,留空即可 function end_lvl(&$output, $depth, $args) {} // 重写walk方法,最后输出两个独立的select框 function walk($elements, $max_depth) { parent::walk($elements, $max_depth); // 拼接父级select的HTML $parent_select = '<select id="parent-menu-select" name="parent-menu">'; $parent_select .= '<option value="">请选择父级菜单</option>'; $parent_select .= implode('', $this->parent_items); $parent_select .= '</select>'; // 拼接子级select的HTML $child_select = '<select id="child-menu-select" name="child-menu">'; $child_select .= '<option value="">请选择子级菜单</option>'; $child_select .= implode('', $this->child_items); $child_select .= '</select>'; // 返回最终的组合HTML return $parent_select . '<br>' . $child_select; } }
调用这个Walker的方法
在你的主题模板文件(比如header.php)里,用wp_nav_menu调用这个自定义Walker即可:
wp_nav_menu([ 'theme_location' => 'your-menu-location', // 替换成你后台设置的菜单位置 'walker' => new My_Walker_Nav_Menu_Language(), 'container' => false, // 禁用WordPress默认的容器div ]);
额外优化建议
- 子级菜单联动:如果需要实现「选择父级后只显示对应子级」的交互,可以添加一段简单的JavaScript:
document.getElementById('parent-menu-select').addEventListener('change', function() { const selectedParent = this.options[this.selectedIndex].text; const childOptions = document.querySelectorAll('#child-menu-select option'); childOptions.forEach(option => { if (option.value === '' || option.textContent.includes(selectedParent)) { option.style.display = 'block'; } else { option.style.display = 'none'; } }); // 切换父级后重置子级选择 document.getElementById('child-menu-select').selectedIndex = 0; });
- 安全规范:代码里用到的
esc_url()和esc_html()是WordPress开发的安全最佳实践,能有效防止XSS攻击,建议保留。
内容的提问来源于stack exchange,提问作者tibewww
相关产品推荐
相关产品推荐

