WooCommerce动态产品分类导航:显示同级与直接子分类列表
在WooCommerce电商平台搭建过程中,很多商家希望在前台产品分类页面展示更灵活的导航结构,比如显示当前分类的同级分类,或者当前分类的直接子分类,方便用户快速切换浏览同层级或下一级分类的产品。本文将介绍如何通过自定义代码实现这种动态分类导航功能,无需依赖第三方插件,适配绝大多数WooCommerce主题。
核心实现逻辑
要实现动态分类导航,核心是获取当前产品分类的层级信息:首先判断当前页面是否为产品分类归档页,然后获取当前分类的父分类ID,根据父分类ID的不同情况分别处理——如果当前分类是顶级分类(父分类ID为0),则显示所有顶级分类作为同级列表;如果当前分类有父分类,则获取父分类下的所有子分类作为同级列表,同时获取当前分类的直接子分类作为子分类列表。
完整代码实现
将以下代码添加到当前主题的functions.php文件中,或者直接添加到自定义代码片段插件中即可生效:
// 显示WooCommerce产品分类的动态导航(同级+直接子分类)
function display_wc_category_navigation() {
// 仅在产品分类归档页执行
if (!is_product_category()) {
return;
}
// 获取当前产品分类对象
$current_term = get_queried_object();
if (!$current_term || !isset($current_term->term_id)) {
return;
}
$current_term_id = $current_term->term_id;
$parent_term_id = $current_term->parent;
$output = '';
// 1. 处理同级分类列表
$output .= '<div class="wc-sibling-categories">';
$output .= '<h3>同级分类</h3>';
$output .= '<ul>';
if ($parent_term_id == 0) {
// 当前是顶级分类,获取所有顶级产品分类
$sibling_args = array(
'taxonomy' => 'product_cat',
'parent' => 0,
'hide_empty' => false,
'exclude' => array($current_term_id) // 排除当前分类
);
} else {
// 当前是子分类,获取父分类下的所有子分类
$sibling_args = array(
'taxonomy' => 'product_cat',
'parent' => $parent_term_id,
'hide_empty' => false,
'exclude' => array($current_term_id)
);
}
$sibling_terms = get_terms($sibling_args);
if (!empty($sibling_terms) && !is_wp_error($sibling_terms)) {
foreach ($sibling_terms as $term) {
$term_link = get_term_link($term);
$output .= '<li><a href="' . esc_url($term_link) . '">' . esc_html($term->name) . '</a></li>';
}
} else {
$output .= '<li>暂无其他同级分类</li>';
}
// 添加当前分类到同级列表并标记为当前项
$current_link = get_term_link($current_term);
$output .= '<li class="current-cat"><a href="' . esc_url($current_link) . '">' . esc_html($current_term->name) . '</a></li>';
$output .= '</ul></div>';
// 2. 处理直接子分类列表
$child_args = array(
'taxonomy' => 'product_cat',
'parent' => $current_term_id,
'hide_empty' => false
);
$child_terms = get_terms($child_args);
if (!empty($child_terms) && !is_wp_error($child_terms)) {
$output .= '<div class="wc-child-categories">';
$output .= '<h3>子分类</h3>';
$output .= '<ul>';
foreach ($child_terms as $term) {
$term_link = get_term_link($term);
$output .= '<li><a href="' . esc_url($term_link) . '">' . esc_html($term->name) . '</a></li>';
}
$output .= '</ul></div>';
}
echo $output;
}
// 将导航挂载到产品分类内容前
add_action('woocommerce_before_main_content', 'display_wc_category_navigation', 20);代码说明
上述代码首先通过is_product_category()判断当前页面是否为产品分类页,避免在非分类页输出导航。接着通过get_queried_object()获取当前分类的完整信息,包括分类ID和父分类ID。
处理同级分类时,先判断父分类ID是否为0:如果是顶级分类,就查询所有父分类ID为0的产品分类,排除当前分类后输出;如果有父分类,就查询父分类下的所有子分类,同样排除当前分类。最后再把当前分类追加到同级列表的末尾,并添加current-cat类方便样式标记。
处理子分类时,直接查询父分类ID为当前分类ID的所有产品分类,如果有结果就输出子分类列表,没有则不会显示子分类区块。
样式自定义建议
如果需要调整导航的显示样式,可以在主题的style.css中添加以下基础样式,也可以根据自身需求修改:
/* 产品分类导航整体样式 */
.wc-sibling-categories, .wc-child-categories {
margin-bottom: 20px;
padding: 15px;
background-color: #f8f8f8;
border-radius: 4px;
}
.wc-sibling-categories h3, .wc-child-categories h3 {
margin-top: 0;
font-size: 16px;
color: #333;
margin-bottom: 10px;
}
.wc-sibling-categories ul, .wc-child-categories ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.wc-sibling-categories li, .wc-child-categories li {
margin: 0;
}
.wc-sibling-categories a, .wc-child-categories a {
display: inline-block;
padding: 6px 12px;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 3px;
color: #666;
text-decoration: none;
font-size: 14px;
transition: all 0.2s ease;
}
.wc-sibling-categories a:hover, .wc-child-categories a:hover {
background-color: #f0f0f0;
border-color: #ccc;
color: #333;
}
/* 当前分类标记样式 */
.wc-sibling-categories .current-cat a {
background-color: #0073aa;
border-color: #0073aa;
color: #fff;
}注意事项
1. 代码中使用hide_empty参数设置为false,会显示没有产品的分类,如果希望只显示有产品的分类,可以将该参数改为true。
2. 如果主题已经修改了WooCommerce的默认钩子优先级,可能需要调整add_action中的优先级数值,确保导航显示在合适的位置。
3. 若要修改导航的显示位置,可以更换挂载的钩子,比如挂载到woocommerce_after_main_content就会显示在内容区域下方。