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

如何获取含促销商品的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>

关键说明

  1. 辅助函数逻辑:has_sale_products_in_category函数会获取当前分类及其所有子分类的ID,然后用wc_get_products查询是否存在促销商品,设置limit=1来提升查询效率,因为我们只需要知道是否存在至少一个促销商品即可。
  2. 分类过滤:我们先获取所有分类(设置hide_empty=false),然后用辅助函数过滤掉没有促销商品的分类,这样就能保证只要子类有促销,父类会被保留(因为父类的辅助函数检查会包含子分类的促销商品)。
  3. 安全优化:使用esc_url和esc_html来防止XSS安全问题,这是WordPress开发的最佳实践。
  4. 层级保留:代码保留了你原来的三级分类结构(父>子>孙),并且每个层级都会过滤掉没有促销商品的分类。

内容的提问来源于stack exchange,提问作者Robert Zalinyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:12:52