WooCommerce中如何区分单个产品页主产品与相关/追加销售轮播产品以实现不同价格显示
WooCommerce中如何区分单个产品页主产品与相关/追加销售轮播产品以实现不同价格显示
嘿,这个问题我之前也帮不少人解决过,确实用is_product() && is_main_query()会踩坑——因为相关产品和追加销售的查询虽然在单产品页里,但它们并没有替换主查询,所以is_main_query()还是会返回true,导致你的判断失效。
给你两个靠谱的解决方案,都是基于WooCommerce自带的上下文判断,不用依赖第三方插件的参数:
方法一:利用WooCommerce循环属性判断(最推荐)
WooCommerce在渲染产品循环时会设置循环属性,相关产品、追加销售这类特殊循环都会有对应的名称标识。我们可以用wc_get_loop_prop('name')来获取当前循环的名称,以此区分主产品和轮播产品:
// 替换成你实际使用的第三方插件钩子,这里以woocommerce_get_price_html为例 add_filter('woocommerce_get_price_html', 'custom_price_display_by_context', 10, 2); function custom_price_display_by_context($price_html, $product) { // 判断是否在单产品页的主产品区域 if (is_product() && !wc_get_loop_prop('name')) { // 这里是主产品的价格显示逻辑 return '<span class="main-product-price">【主产品】' . $price_html . '</span>'; } else { // 这里是轮播产品(相关、追加销售)或其他页面的价格显示逻辑 return '<span class="carousel-product-price">【轮播产品】' . $price_html . '</span>'; } }
原理说明:
- 单产品页的主产品渲染时,没有设置循环名称,所以
wc_get_loop_prop('name')会返回false; - 相关产品循环的名称是
related,追加销售是upsells,其他自定义轮播也可能有对应的名称(比如featured),这些情况下wc_get_loop_prop('name')会返回具体的名称字符串。
方法二:通过全局查询对象辅助判断
如果你的第三方钩子执行时机比较特殊,也可以通过全局$wp_query对象来辅助判断,不过这个方法兼容性稍弱一点:
add_filter('woocommerce_get_price_html', 'custom_price_display_by_query', 10, 2); function custom_price_display_by_query($price_html, $product) { global $wp_query; // 先确认是单产品页 if (!is_product()) { return $price_html; } // 主产品的ID和当前查询的ID一致,而轮播产品的ID会和主查询ID不同 if ($product->get_id() === $wp_query->get_queried_object_id()) { // 主产品价格显示 return '<span class="main-product-price">【主产品】' . $price_html . '</span>'; } else { // 轮播产品价格显示 return '<span class="carousel-product-price">【轮播产品】' . $price_html . '</span>'; } }
原理说明:
单产品页的主查询ID就是当前主产品的ID,而相关/追加销售的产品ID肯定和主查询ID不一样,通过这个对比就能区分开。
如果你的第三方钩子没有传递$product参数,也可以用global $product;在函数内部获取当前产品对象,一样能正常工作。
备注:内容来源于stack exchange,提问作者James B.
相关产品推荐
相关产品推荐

