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

WordPress自定义菜单:基于分类父项动态展示产品文章子菜单(短代码)

实现WordPress自定义菜单动态加载产品文章的短代码方案

问题背景

我有一个名为products的自定义文章类型(Custom Post Type),存储着产品列表。已在WordPress后台「外观 > 菜单」中创建了如下层级菜单:

Electronics
  -> Camera
  -> Headphones
  -> Tv accessories
Computers
  -> Monitors
  -> Keyboards
  -> Mouse
Stationaries
  -> Pen
  -> Pencil
  -> Notebooks
-> Paper

需要通过短代码展示该菜单,并且实现点击子菜单(如Camera)时,动态加载属于Electronics/Camera分类下的products类型文章作为二级子菜单,最终结构如下:

Electronics
-> Camera
  --> 属于Electronics/Camera分类的products文章列表(动态加载)

目前使用以下代码生成菜单短代码,但无法实现基于父菜单条件的动态文章加载:

function custom_hierarchical_menu() {
    // 获取生成的菜单HTML,不直接输出
    $menu_html = wp_nav_menu( array(
        'menu'   => 'Hierarchy Desktop Menu',
        'echo'   => false, // 设置为false将HTML存入变量
    ) );
    
    return $menu_html;
}

add_shortcode( 'customHierarchicalMenu', 'custom_hierarchical_menu');

解决方案

1. 关联菜单项与产品分类

首先需要给每个需要加载产品的菜单项(如Camera)标记对应的分类slug:

  • 可以用**Advanced Custom Fields(ACF)**插件,创建一个针对nav_menu_item的字段组,添加文本字段menu_category_slug用于填写分类slug;
  • 或者用以下代码手动添加自定义字段:
// 添加菜单编辑页面的自定义字段
function add_menu_category_meta_box() {
    add_meta_box(
        'menu_category_meta',
        '关联产品分类',
        'render_menu_category_meta_box',
        'nav_menu_item',
        'side',
        'default'
    );
}
add_action('add_meta_boxes_nav_menu_item', 'add_menu_category_meta_box');

// 渲染自定义字段输入框
function render_menu_category_meta_box($item) {
    $category_slug = get_post_meta($item->ID, 'menu_category_slug', true);
    ?>
    <p>
        <label for="menu_category_slug">分类Slug:</label>
        <input type="text" id="menu_category_slug" name="menu_category_slug[<?php echo $item->ID; ?>]" value="<?php echo esc_attr($category_slug); ?>">
    </p>
    <?php
}

// 保存自定义字段值
function save_menu_category_meta($menu_id, $menu_item_db_id) {
    if (isset($_POST['menu_category_slug'][$menu_item_db_id])) {
        update_post_meta($menu_item_db_id, 'menu_category_slug', sanitize_text_field($_POST['menu_category_slug'][$menu_item_db_id]));
    }
}
add_action('wp_update_nav_menu_item', 'save_menu_category_meta', 10, 2);

添加后,在菜单编辑页面给每个需要加载产品的子项填写对应的分类slug(比如Camera对应camera)。

2. 自定义菜单Walker类

通过自定义Walker_Nav_Menu类,在遍历菜单时自动查询并插入对应分类的产品列表:

class Custom_Menu_Walker extends Walker_Nav_Menu {
    // 在菜单项结束时插入产品列表
    function end_el(&$output, $item, $depth = 0, $args = null) {
        // 获取当前菜单项关联的分类slug
        $category_slug = get_post_meta($item->ID, 'menu_category_slug', true);
        
        // 只给二级菜单(depth=1)添加产品子菜单
        if ($category_slug && $depth === 1) {
            // 查询对应分类下的products文章
            $products_query = new WP_Query(array(
                'post_type'      => 'products',
                'posts_per_page' => -1, // 显示所有产品
                'tax_query'      => array(
                    array(
                        'taxonomy' => 'category', // 若使用自定义分类,请替换为你的分类taxonomy(如product_category)
                        'field'    => 'slug',
                        'terms'    => $category_slug,
                    )
                )
            ));
            
            if ($products_query->have_posts()) {
                $output .= '<ul class="product-submenu">';
                while ($products_query->have_posts()) {
                    $products_query->the_post();
                    $output .= sprintf('<li><a href="%s">%s</a></li>', get_permalink(), get_the_title());
                }
                $output .= '</ul>';
                wp_reset_postdata(); // 重置查询
            }
        }
        
        parent::end_el($output, $item, $depth, $args);
    }
}

3. 更新短代码函数,使用自定义Walker

修改原有短代码函数,指定使用我们创建的Walker类:

function custom_hierarchical_menu() {
    $menu_html = wp_nav_menu( array(
        'menu'        => 'Hierarchy Desktop Menu',
        'echo'        => false,
        'walker'      => new Custom_Menu_Walker(), // 启用自定义Walker
        'menu_class'  => 'custom-hierarchy-menu', // 添加自定义类名方便样式控制
    ) );
    
    return $menu_html;
}
add_shortcode( 'customHierarchicalMenu', 'custom_hierarchical_menu');

4. 添加前端交互(可选)

如果需要点击菜单项才展开产品列表(默认隐藏),可以添加以下JS和CSS:

JavaScript(实现点击展开/收起)

document.addEventListener('DOMContentLoaded', function() {
    const menuItems = document.querySelectorAll('.custom-hierarchy-menu li.menu-item-depth-1');
    menuItems.forEach(item => {
        item.addEventListener('click', function(e) {
            e.preventDefault();
            const submenu = this.querySelector('.product-submenu');
            if (submenu) submenu.classList.toggle('active');
        });
    });
});

CSS(控制子菜单显示/隐藏)

.product-submenu {
    display: none;
    margin-left: 20px;
    list-style-type: disc;
}
.product-submenu.active {
    display: block;
}

注意事项

  • 若使用自定义分类(而非WordPress默认分类),需将WP_Query中tax_query的taxonomy值替换为你的自定义分类slug(比如product_category);
  • 可根据需求调整posts_per_page参数,限制显示的产品数量;
  • 样式可根据网站设计自行修改,确保菜单层级清晰。

内容的提问来源于stack exchange,提问作者Eunice Dhivya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:05:19