WooCommerce:在自定义产品循环中按分类ID筛选产品

碧海醫心
发布: 2025-09-28 08:49:01
原创
242人浏览过

WooCommerce:在自定义产品循环中按分类ID筛选产品

本文详细介绍了如何在WooCommerce自定义产品归档模板中,利用 wc_get_products 函数高效且兼容未来版本地按指定分类ID筛选并显示产品。通过替换传统的 WP_Query 循环,文章提供了完整的代码示例和参数解析,确保开发者能够灵活构建符合特定业务需求的自定义产品展示逻辑。

为什么选择 wc_get_products 而非 WP_Query

在woocommerce中构建自定义产品查询时,官方强烈推荐使用 wc_get_products 和 wc_product_query,而非传统的 wp_query 或直接的数据库查询。这是因为woocommerce未来可能会将产品数据迁移到自定义表中以提升性能,而 wc_get_products 提供了一个标准且安全的接口,能够确保代码的未来兼容性,避免因数据库结构变化导致代码失效。当我们需要在自定义模板中仅显示特定分类下的产品时,wc_get_products 是实现这一目标的最佳实践。

创建自定义 WooCommerce 产品归档模板

首先,为了实现自定义的产品展示逻辑,我们需要创建一个自定义的WooCommerce模板。

  1. 复制基础模板: 将 woocommerce/archive-product.php 文件复制到你的子主题的 woocommerce 文件夹中。

  2. 重命名并添加模板注释: 将复制的文件重命名为,例如 custom-category-archive.php。然后,在文件顶部添加模板注释,使其可以作为页面模板在WordPress后台选择:

    <?php
    /*
    Template Name: 自定义分类产品归档模板
    */
    ?>
    登录后复制

    通过这种方式,你可以在WordPress页面编辑界面中选择这个模板来展示特定内容。

构建按分类 ID 筛选的自定义产品循环

在 custom-category-archive.php 模板中,我们将替换或修改标准的WooCommerce产品循环,以使用 wc_get_products 来筛选特定分类的产品。

标准的WooCommerce产品循环通常如下所示:

百度文心百中
百度文心百中

百度大模型语义搜索体验中心

百度文心百中 22
查看详情 百度文心百中
if ( woocommerce_product_loop() ) {
    do_action( 'woocommerce_before_shop_loop' );
    woocommerce_product_loop_start();
    if ( wc_get_loop_prop( 'total' ) ) {
        while ( have_posts() ) {
            the_post();
            do_action( 'woocommerce_shop_loop' );
            wc_get_template_part( 'content', 'product' );
        }
    }
    woocommerce_product_loop_end();
}
登录后复制

要按分类ID筛选,我们将用 wc_get_products 构建一个全新的循环。以下是完整的代码示例,你可以在 custom-category-archive.php 文件中 get_header( 'shop' ); 之后,do_action( 'woocommerce_before_main_content' ); 之前或之后添加:

<?php
defined( 'ABSPATH' ) || exit;

get_header( 'shop' );

do_action( 'woocommerce_before_main_content' );

// 确保 wc_get_products 函数存在,增强代码健壮性
if ( ! function_exists( 'wc_get_products' ) ) {
    return;
}

// 获取WooCommerce的排序参数
$ordering            = WC()->query->get_catalog_ordering_args();
$ordering['orderby'] = array_shift( explode( ' ', $ordering['orderby'] ) );
// 根据排序字段调整 orderby 参数,例如价格排序需要特殊处理
$ordering['orderby'] = stristr( $ordering['orderby'], 'price' ) ? 'meta_value_num' : $ordering['orderby'];

// 定义 wc_get_products 的查询参数
$args = array(
    'status'       => 'publish', // 只获取已发布的产品
    'limit'        => -1,        // 获取所有匹配的产品,不限制数量
    'paginate'     => true,      // 启用分页,方便获取总数
    'return'       => 'ids',     // 只返回产品ID,减少内存消耗,提高性能
    'orderby'      => $ordering['orderby'], // 继承WooCommerce的排序方式
    'order'        => $ordering['order'],   // 继承WooCommerce的排序顺序
    'tax_query'    => array(
        array(
            'taxonomy' => 'product_cat', // 针对产品分类
            'field'    => 'term_id',     // 通过分类ID进行查询
            'terms'    => array( 12, 345, 7899 ), // 指定要包含的分类ID,请替换为你的实际ID
            'operator' => 'IN',          // 包含在指定ID列表中的分类
        )
    ),
    // 其他可选参数,例如库存状态和可见性
    // 'stock_status' => 'instock', // 只显示有库存的产品
    // 'visibility'   => 'visible', // 只显示可见的产品
);

// 执行产品查询
$cat_products = wc_get_products( $args );

// 设置循环属性,确保WooCommerce的其他组件(如结果计数、分页)能正确工作
wc_set_loop_prop( 'total', $cat_products->total );
wc_set_loop_prop( 'total_pages', $cat_products->max_num_pages ); // 如果需要分页,设置总页数

// 检查是否有产品
if ( $cat_products && ! empty( $cat_products->products ) ) {
    do_action( 'woocommerce_before_shop_loop' );

    echo '<div class="woocommerce-products-loop">'; // 自定义容器,可根据需要修改

    foreach ( $cat_products->products as $product_id ) {
        // 获取产品对象并设置全局 $post 变量
        $post_object = get_post( $product_id );
        setup_postdata( $GLOBALS['post'] =& $post_object );

        // 获取产品实例,用于 wc_product_class
        $product = wc_get_product( $product_id );

        // 渲染单个产品内容,利用WooCommerce的钩子和模板部分
        echo '<div '; wc_product_class( ' ', $product ); echo '>';

            do_action( 'woocommerce_before_shop_loop_item' );       // 产品循环项开始前的钩子
            do_action( 'woocommerce_before_shop_loop_item_title' ); // 产品标题前的钩子
            do_action( 'woocommerce_shop_loop_item_title' );        // 产品标题钩子
            do_action( 'woocommerce_after_shop_loop_item_title' );  // 产品标题后的钩子
            do_action( 'woocommerce_after_shop_loop_item' );        // 产品循环项结束后的钩子

        echo '</div>';
    }
    wp_reset_postdata(); // 重置全局 $post 变量,避免影响后续查询

    echo '</div>'; // 结束自定义容器

    do_action( 'woocommerce_after_shop_loop' );
} else {
    // 如果没有找到产品
    do_action( 'woocommerce_no_products_found' );
}

do_action( 'woocommerce_after_main_content' );

get_footer( 'shop' );
登录后复制

关键参数解析与注意事项

  1. wc_get_products($args) 参数:

    • status: 查询产品的状态,如 publish(已发布)。
    • limit: 每页显示的产品数量。设置为 -1 表示不限制,获取所有匹配产品。
    • paginate: 设置为 true 时,wc_get_products 会返回一个 WC_Product_Query 对象,其中包含 total(总产品数)和 max_num_pages(总页数),这对于正确显示分页和结果计数至关重要。
    • return: 指定返回值的类型。设置为 ids 可以只返回产品ID数组,这在仅需遍历产品并渲染时能有效减少内存消耗。
    • orderby 和 order: 用于控制产品排序。示例中继承了WooCommerce商店页面的默认排序设置。
    • tax_query: 这是实现按分类筛选的核心。它是一个数组,每个元素定义一个分类法查询。
      • taxonomy: 指定分类法的名称,对于产品分类,通常是 product_cat。
      • field: 指定用于查询的分类字段,term_id 表示通过分类ID。
      • terms: 一个数组,包含你希望包含(或排除)的分类ID。请注意,这里的ID应为整数,如 array(12, 345, 7899)。
      • operator: 操作符,如 IN(包含在列表内)、NOT IN(不包含在列表内)等。
  2. wc_set_loop_prop('total', $cat_products->total);: 这一行代码非常重要。它将自定义查询获取的产品总数传递给WooCommerce的全局循环属性。这样,woocommerce_result_count 等钩子函数才能正确显示“显示 x 到 y 共 z 个结果”这样的信息,并且分页功能也能基于正确的产品总数进行计算。

  3. 循环迭代与产品渲染:

    • foreach ( $cat_products->products as $product_id ): 遍历 wc_get_products 返回的产品ID。
    • setup_postdata( $GLOBALS['post'] =& $post_object );: 这一步是关键!它将当前产品ID对应的 WP_Post 对象设置为全局 $post 变量,使得所有依赖于 $post 变量的WordPress和WooCommerce模板函数(如 the_title()、the_permalink()、wc_get_template_part() 等)都能正确获取到当前产品的数据。
    • wp_reset_postdata();: 在循环结束后,务必调用此函数,以将全局 $post 变量恢复到主查询的状态,避免影响页面其他部分的查询。
    • do_action(...): 利用WooCommerce提供的各种动作钩子,可以方便地在产品循环的各个阶段插入自定义内容或调用WooCommerce的默认渲染函数,如 wc_get_template_part( 'content', 'product' );(在自定义循环中,我们手动调用了多个子钩子来模拟 content-product.php 的渲染)。
  4. 获取分类ID: 在示例中,分类ID是硬编码的 array( 12, 345, 7899 )。在实际应用中,这些ID可能需要动态获取,例如:

    • 从URL参数获取。
    • 从自定义字段(如 ACF)获取。
    • 通过 get_term_by() 函数根据分类名称或 slug 获取 ID。

总结

通过 wc_get_products 函数,我们可以强大而灵活地控制WooCommerce产品循环,实现按分类ID筛选等复杂需求,同时保持与WooCommerce未来版本的兼容性。在构建自定义模板时,理解 wc_get_products 的参数、wc_set_loop_prop 的作用以及 setup_postdata/wp_reset_postdata 的必要性,将帮助你创建高效、健壮且易于维护的WooCommerce解决方案。始终优先使用官方推荐的 wc_get_products 接口,以确保你的代码在长期运行中的稳定性和性能。

以上就是WooCommerce:在自定义产品循环中按分类ID筛选产品的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号