You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress分类菜单开发:自定义Custom Walker实现父项重复为子项的折叠菜单问题

我懂你要做的这种折叠菜单——展开父分类后,子列表顶部再放一个可点击的父项入口,这种设计在内容导航里特别贴心,用户不用退回就能快速回到父分类。结合你用Walker_Category的场景,我帮你调整了代码,刚好能实现你要的结构:

<ul>
<?php
class Walker_Simple_Example extends Walker_Category {
    // 临时存储当前顶级父分类的信息,用于子列表顶部重复显示
    private $current_parent = array();

    // 渲染每个菜单项的起始部分
    function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
        extract($args);

        // 仅当当前项是顶级父分类且有子项时,保存它的名称和链接
        if ( $depth === 0 && $category->category_parent === 0 && $category->count > 0 ) {
            $this->current_parent = array(
                'name' => $category->name,
                'link' => get_category_link($category)
            );
        }

        // 正常输出当前分类的链接
        $output .= '<li>';
        $output .= '<a href="' . esc_url(get_category_link($category)) . '">' . esc_html($category->name) . '</a>';
    }

    // 子列表开始时,插入重复的父分类链接
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $output .= '<ul class="sub-menu">';
        
        // 只在顶级父分类的子列表顶部插入重复项
        if ( $depth === 0 && !empty($this->current_parent) ) {
            $output .= sprintf(
                '<li class="parent-repeat"><a href="%s">%s</a></li>',
                esc_url($this->current_parent['link']),
                esc_html($this->current_parent['name'])
            );
        }
    }

    // 子列表结束时,清空存储的父分类信息,避免污染下一个父项
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $output .= '</ul>';
        if ( $depth === 0 ) {
            $this->current_parent = array();
        }
    }

    // 渲染每个菜单项的结束部分
    function end_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
        $output .= '</li>';
    }
}

// 调用这个Walker输出分类菜单
wp_list_categories(array(
    'walker' => new Walker_Simple_Example(),
    'hierarchical' => true,
    'show_count' => false,
    'title_li' => ''
));
?>
</ul>

关键逻辑说明:

  • $current_parent私有属性:专门用来临时存当前顶级父分类的名称和链接,这样子列表渲染时能直接调用。
  • start_el方法:判断当前项是顶级父分类且有子项时,才把它的信息存起来,避免无意义的存储。
  • start_lvl方法:当子列表开始(depth=0对应顶级父项的子列表),就插入之前存的父分类链接,还加了parent-repeat类方便你做样式区分(比如加个返回图标)。
  • end_lvl方法:子列表结束时清空存储的父分类信息,防止下一个父分类继承错误的内容。

额外提示:

  • 如果要支持多级子分类(比如父→子→孙,孙列表顶部显示子项),只需要调整start_lvl里的$depth判断条件(比如改成$depth === 1)。
  • 确保wp_list_categories的hierarchical参数设为true,不然层级菜单不会生效。
  • 可以根据需求修改sub-menu和parent-repeat的类名,适配你的CSS样式。

内容的提问来源于stack exchange,提问作者ragu.design

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:51:01