
在woocommerce中构建自定义产品查询时,官方强烈推荐使用 wc_get_products 和 wc_product_query,而非传统的 wp_query 或直接的数据库查询。这是因为woocommerce未来可能会将产品数据迁移到自定义表中以提升性能,而 wc_get_products 提供了一个标准且安全的接口,能够确保代码的未来兼容性,避免因数据库结构变化导致代码失效。当我们需要在自定义模板中仅显示特定分类下的产品时,wc_get_products 是实现这一目标的最佳实践。
首先,为了实现自定义的产品展示逻辑,我们需要创建一个自定义的WooCommerce模板。
复制基础模板: 将 woocommerce/archive-product.php 文件复制到你的子主题的 woocommerce 文件夹中。
重命名并添加模板注释: 将复制的文件重命名为,例如 custom-category-archive.php。然后,在文件顶部添加模板注释,使其可以作为页面模板在WordPress后台选择:
<?php /* Template Name: 自定义分类产品归档模板 */ ?>
通过这种方式,你可以在WordPress页面编辑界面中选择这个模板来展示特定内容。
在 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' ); 之前或之后添加:
<?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' );wc_get_products($args) 参数:
wc_set_loop_prop('total', $cat_products->total);: 这一行代码非常重要。它将自定义查询获取的产品总数传递给WooCommerce的全局循环属性。这样,woocommerce_result_count 等钩子函数才能正确显示“显示 x 到 y 共 z 个结果”这样的信息,并且分页功能也能基于正确的产品总数进行计算。
循环迭代与产品渲染:
获取分类ID: 在示例中,分类ID是硬编码的 array( 12, 345, 7899 )。在实际应用中,这些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中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号