WooCommerce教程:构建动态产品分类导航,含同级与一级子分类
在电商网站中,清晰的产品分类导航能帮助用户快速定位目标商品,提升浏览体验。WooCommerce作为WordPress生态下主流的电商插件,默认的分类导航功能较为基础,很多时候我们需要根据当前访问的分类动态展示相关的同级分类和一级子分类。本文将详细介绍如何实现这样的动态导航功能,适用于需要在分类页面展示关联分类的场景。
功能需求说明
我们要实现的效果是:当用户访问某个产品分类页面时,导航栏自动展示以下内容:
- 如果当前分类是顶级分类:展示所有顶级产品分类
- 如果当前分类是子分类:展示其所有同级子分类,以及当前分类所属顶级分类的所有一级子分类
这样可以让用户在分类层级之间快速切换,无需反复返回上级页面查找相关分类。
实现步骤
1. 获取当前产品分类信息
首先需要通过WordPress的查询对象获取当前访问的产品分类信息,包括分类ID、父级分类ID等核心参数。
// 获取当前产品分类对象
$current_term = get_queried_object();
// 判断当前是否为产品分类页面
if (is_product_category() && !empty($current_term) && is_a($current_term, 'WP_Term')) {
$current_term_id = $current_term->term_id;
$current_parent_id = $current_term->parent;
$taxonomy = 'product_cat'; // WooCommerce产品分类的固定分类法名称
} else {
// 非产品分类页面不执行后续逻辑
return;
}2. 计算需要展示的分类范围
根据当前分类的层级,确定要查询的父级分类ID:如果是顶级分类,父级ID为0;如果是子分类,则取其顶级父级ID作为查询一级子分类的依据。
// 获取顶级父级分类ID
if ($current_parent_id == 0) {
// 当前是顶级分类,顶级父级就是自己
$top_parent_id = $current_term_id;
} else {
// 递归获取顶级父级分类
$ancestors = get_ancestors($current_term_id, $taxonomy);
$top_parent_id = end($ancestors);
// 如果没取到顶级父级,默认用当前分类的父级
if (empty($top_parent_id)) {
$top_parent_id = $current_parent_id;
}
}3. 查询对应的分类数据
分别查询需要展示的顶级分类下的一级子分类,以及当前分类的同级分类,同时排除空分类(没有产品的分类)。
// 查询参数:排除空分类,按名称排序
$cat_args = array(
'taxonomy' => $taxonomy,
'hide_empty' => true,
'orderby' => 'name',
'order' => 'ASC'
);
// 查询顶级父级下的一级子分类
$top_children_args = $cat_args;
$top_children_args['parent'] = $top_parent_id;
$top_children_cats = get_terms($top_children_args);
// 查询当前分类的同级分类(父级相同的分类)
$sibling_args = $cat_args;
if ($current_parent_id == 0) {
// 当前是顶级分类,同级就是所有顶级分类
$sibling_args['parent'] = 0;
} else {
$sibling_args['parent'] = $current_parent_id;
}
$sibling_cats = get_terms($sibling_args);4. 渲染导航结构
将查询到的分类数据渲染为前端可见的导航列表,同时高亮当前访问的分类。
// 如果没有查询到分类,直接返回
if (empty($top_children_cats) && empty($sibling_cats)) {
return;
}
?>
<div class="product-cat-nav">
<ul class="cat-nav-list">
<?php
// 先渲染同级分类
if (!empty($sibling_cats)) {
foreach ($sibling_cats as $cat) {
$is_current = ($cat->term_id == $current_term_id) ? 'class="current-cat"' : '';
$cat_link = get_term_link($cat, $taxonomy);
// 处理链接获取失败的情况
if (is_wp_error($cat_link)) {
continue;
}
?>
<li <?php echo $is_current; ?>>
<a href="<?php echo esc_url($cat_link); ?>">
<?php echo esc_html($cat->name); ?>
</a>
</li>
<?php
}
}
// 如果顶级子分类和同级分类不同,再渲染顶级一级子分类
// 避免重复展示相同分类
$sibling_ids = wp_list_pluck($sibling_cats, 'term_id');
if (!empty($top_children_cats)) {
foreach ($top_children_cats as $cat) {
// 跳过已经在同级中展示过的分类
if (in_array($cat->term_id, $sibling_ids)) {
continue;
}
$is_current = ($cat->term_id == $current_term_id) ? 'class="current-cat"' : '';
$cat_link = get_term_link($cat, $taxonomy);
if (is_wp_error($cat_link)) {
continue;
}
?>
<li <?php echo $is_current; ?>>
<a href="<?php echo esc_url($cat_link); ?>">
<?php echo esc_html($cat->name); ?>
</a>
</li>
<?php
}
}
?>
</ul>
</div>
<?php样式优化建议
为了让导航更符合网站整体风格,可以添加基础的CSS样式,以下是参考样式:
.product-cat-nav {
margin: 20px 0;
padding: 15px;
background: #f7f7f7;
border-radius: 6px;
}
.cat-nav-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.cat-nav-list li {
margin: 0;
}
.cat-nav-list li a {
display: inline-block;
padding: 8px 16px;
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
color: #333;
text-decoration: none;
font-size: 14px;
transition: all 0.2s ease;
}
.cat-nav-list li a:hover {
background: #007cba;
color: #fff;
border-color: #007cba;
}
.cat-nav-list li.current-cat a {
background: #007cba;
color: #fff;
border-color: #007cba;
font-weight: 600;
}注意事项
1. 上述代码建议放在主题的functions.php中封装为函数,然后在分类模板文件中调用,避免直接修改核心插件文件。
2. 如果网站使用了分类缓存插件,修改分类后需要清除缓存才能使导航更新生效。
3. 若需要排除特定分类,可以在查询参数中添加exclude选项,传入对应分类ID即可。
4. 当需要展示更多层级分类时,可以调整get_ancestors的逻辑,获取更完整的分类层级树。