
本文详细介绍了如何在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模板。
复制基础模板: 将 woocommerce/archive-product.php 文件复制到你的子主题的 woocommerce 文件夹中。
重命名并添加模板注释: 将复制的文件重命名为,例如 custom-category-archive.php。然后,在文件顶部添加模板注释,使其可以作为页面模板在WordPress后台选择:
通过这种方式,你可以在WordPress页面编辑界面中选择这个模板来展示特定内容。
构建按分类 ID 筛选的自定义产品循环
在 custom-category-archive.php 模板中,我们将替换或修改标准的WooCommerce产品循环,以使用 wc_get_products 来筛选特定分类的产品。
标准的WooCommerce产品循环通常如下所示:
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’ ); 之前或之后添加:
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 ''; // 自定义容器,可根据需要修改 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 ''; 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 ''; } wp_reset_postdata(); // 重置全局 $post 变量,避免影响后续查询 echo ''; // 结束自定义容器 do_action( 'woocommerce_after_shop_loop' );} else { // 如果没有找到产品 do_action( 'woocommerce_no_products_found' );}do_action( 'woocommerce_after_main_content' );get_footer( 'shop' );
关键参数解析与注意事项
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(不包含在列表内)等。
wc_set_loop_prop(‘total’, $cat_products->total);:这一行代码非常重要。它将自定义查询获取的产品总数传递给WooCommerce的全局循环属性。这样,woocommerce_result_count 等钩子函数才能正确显示“显示 x 到 y 共 z 个结果”这样的信息,并且分页功能也能基于正确的产品总数进行计算。
循环迭代与产品渲染:
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 的渲染)。
获取分类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中文网其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1322497.html
微信扫一扫
支付宝扫一扫