如何获取含促销商品的WooCommerce产品分类(含父子层级)
解决方案:筛选包含促销商品的WooCommerce分类(带层级结构)
当然可以实现这个需求!我们需要做的核心是检查每个分类(包括其子分类)下是否存在促销商品,同时确保如果子类有促销商品,其父分类也会被显示出来。下面是基于你现有代码修改后的完整实现:
步骤1:添加辅助函数检查促销商品
首先添加一个辅助函数,用来判断某个分类及其子分类下是否有促销商品:
/** * 检查分类及其子分类下是否存在促销商品 * @param int $term_id 分类ID * @return bool */ function has_sale_products_in_category($term_id) { // 获取当前分类及其所有子分类的ID $term_ids = get_term_children($term_id, 'product_cat'); $term_ids[] = $term_id; // 包含当前分类本身 // 查询该分类下的促销商品 $sale_products = wc_get_products(array( 'category' => $term_ids, 'on_sale' => true, 'limit' => 1, // 只要存在至少1个就够了,不用查全部 'return' => 'ids' )); // 如果有促销商品则返回true return !empty($sale_products); }
步骤2:修改分类列表代码
接下来调整你原来的分类渲染代码,加入上面的辅助函数来过滤分类:
<ul class="accordion list-group sub-catalog"> <?php // 获取顶级分类(排除ID15) $parent_terms = get_terms('product_cat', array( 'parent' => 0, 'exclude' => '15', 'hide_empty' => false // 先获取所有顶级分类,之后再过滤 )); if ($parent_terms) { $original_query = $wp_query; foreach ($parent_terms as $parent_term) { // 检查当前顶级分类(含子分类)是否有促销商品 if (!has_sale_products_in_category($parent_term->term_id)) { continue; // 没有促销商品则跳过该分类 } // 获取当前顶级分类的子分类 $child_terms = get_terms('product_cat', array( 'child_of' => $parent_term->term_id, 'hide_empty' => false // 先获取所有子分类,之后再过滤 )); ?> <li class="accordion-card list-group-item"> <div class="acc-card-title"> <a href="<?php echo esc_url(get_term_link($parent_term)); ?>"><?php echo esc_html($parent_term->name); ?></a> <?php if (!empty($child_terms)) : ?> <span class="fa fa-plus"></span> <?php endif; ?> </div> <?php if (!empty($child_terms)) : ?> <ul class="accordion list-group sub-catalog"> <?php foreach ($child_terms as $child_term) { // 检查子分类(含其子分类)是否有促销商品 if (!has_sale_products_in_category($child_term->term_id)) { continue; // 没有促销商品则跳过该子分类 } // 获取子分类的子分类(孙分类) $grandchild_terms = get_terms('product_cat', array( 'child_of' => $child_term->term_id, 'hide_empty' => false )); ?> <li class="accordion-card list-group-item"> <div class="acc-card-title"> <a href="<?php echo esc_url(get_term_link($child_term)); ?>"><?php echo esc_html($child_term->name); ?></a> </div> <?php if (!empty($grandchild_terms)) : ?> <ul class="accordion list-group sub-catalog"> <?php foreach ($grandchild_terms as $grandchild_term) { // 检查孙分类是否有促销商品 if (!has_sale_products_in_category($grandchild_term->term_id)) { continue; } ?> <li class="accordion-card list-group-item"> <div class="acc-card-title"> <a href="<?php echo esc_url(get_term_link($grandchild_term)); ?>"><?php echo esc_html($grandchild_term->name); ?></a> </div> </li> <?php } ?> </ul> <?php endif; ?> </li> <?php } ?> </ul> <?php endif; ?> </li> <?php } $wp_query = null; $wp_query = $original_query; } ?> </ul>
关键说明
- 辅助函数逻辑:
has_sale_products_in_category函数会获取当前分类及其所有子分类的ID,然后用wc_get_products查询是否存在促销商品,设置limit=1来提升查询效率,因为我们只需要知道是否存在至少一个促销商品即可。 - 分类过滤:我们先获取所有分类(设置
hide_empty=false),然后用辅助函数过滤掉没有促销商品的分类,这样就能保证只要子类有促销,父类会被保留(因为父类的辅助函数检查会包含子分类的促销商品)。 - 安全优化:使用
esc_url和esc_html来防止XSS安全问题,这是WordPress开发的最佳实践。 - 层级保留:代码保留了你原来的三级分类结构(父>子>孙),并且每个层级都会过滤掉没有促销商品的分类。
内容的提问来源于stack exchange,提问作者Robert Zalinyan
相关产品推荐
相关产品推荐

