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
相关产品推荐
相关产品推荐

