WooCommerce产品捆绑如何显示选中项价格替换From $起价
WooCommerce Product Bundles 价格显示问题实现方案
问题背景
使用WooCommerce官方插件「WooCommerce Product Bundles」搭建站点时,遇到两类价格显示问题:
- 商品详情页:捆绑商品包含5款默认勾选的可选子商品,但主价格区域默认显示“From 900 kr.”的起价文案,未展示已选中商品的合计价格,仅在捆绑选项下方显示选中商品总价。
- 此前已通过自定义代码实现可变商品主价格区同步选中变体价格的效果,尝试修改适配捆绑商品时调试失败,可变商品原有代码如下:
// Show selected variation price in main price area add_action('woocommerce_before_add_to_cart_form', 'selected_variation_price_replace_variable_price_range'); function selected_variation_price_replace_variable_price_range(){ global $product; if( $product->is_type('variable') ): ?><style> .woocommerce-variation-price {display:none;} </style> <script> jQuery(function($) { var p = 'p.price' q = $(p).html(); $('form.cart').on('show_variation', function( event, data ) { if ( data.price_html ) { $(p).html(data.price_html); } }).on('hide_variation', function( event ) { $(p).html(q); }); }); </script> <?php endif; }
补充问题
通过隐藏详情页默认主价格、调整捆绑选项区总价样式的方式临时解决了详情页显示问题,但分类页(商店循环)仍存在异常:分类页不展示捆绑商品默认选中组合的对应价格,而是显示该捆绑商品的最高可能售价,未匹配默认选中项价格。
插件中控制最高价格显示的相关代码段如下:
/** * 'woocommerce_bundle_force_old_style_price_html' filter. * * Used to suppress the range-style display of bundle price html strings. * * @param boolean $force_suppress_range_format * @param WC_Product_Bundle $this */ if ( $suppress_range_price_html || apply_filters( 'woocommerce_bundle_force_old_style_price_html', false, $this ) ) { $price = wc_price( $price_max ); $regular_price_min = $this->get_bundle_regular_price( 'max', true ); if ( $regular_price_min !== $price_max ) { $regular_price = wc_price( $regular_price_max ); if ( $price_min !== $price_max ) { $price = sprintf( _x( '%1$s%2$s', 'Price range: from', 'woocommerce-product-bundles' ), wc_get_price_html_from_text(), wc_format_sale_price( $regular_price, $price ) . $this->get_price_suffix() ); } else { $price = wc_format_sale_price( $regular_price, $price ) . $this->get_price_suffix(); }
详情页内切换捆绑选项时价格可正常动态更新,说明价格计算逻辑可复用到商店循环场景。
具体实现代码
1. 详情页主价格区同步选中总价(兼容可变商品+捆绑商品)
捆绑商品选项更新时会触发wc-bundles-updated事件,替换原有可变商品的JS监听逻辑即可,无需手动调整CSS修改样式:
add_action('woocommerce_before_add_to_cart_form', 'sync_selected_product_price_to_main_area'); function sync_selected_product_price_to_main_area(){ global $product; if( $product->is_type('variable') || $product->is_type('bundle') ): ?><style> .bundle-wrapper .bundle-price, .woocommerce-variation-price {display:none;} </style> <script> jQuery(function($) { const priceSelector = 'p.price'; const originalPrice = $(priceSelector).html(); // 保留原有可变商品价格同步逻辑 if( $('form.variations_form').length ){ $('form.cart').on('show_variation', function( event, data ) { data.price_html && $(priceSelector).html(data.price_html); }).on('hide_variation', function() { $(priceSelector).html(originalPrice); }); } // 新增捆绑商品价格同步逻辑 if( $('.bundle_form').length ){ // 页面初始化、选项更新时自动同步总价到主价格区 $(document.body).on('wc-bundles-initialized wc-bundles-updated', function(){ const currentPrice = $('.bundle-wrapper .bundle-price').html(); currentPrice && $(priceSelector).html(currentPrice); }); // 重置表单时恢复初始价格 $('.bundle_form').on('reset_data', function(){ $(priceSelector).html(originalPrice); }); } }); </script> <?php endif; }
2. 分类页(商店循环)显示默认选中组合价格
分类页价格为PHP静态输出,直接通过过滤器替换原有区间/最高价格为默认选中项价格即可:
add_filter('woocommerce_get_price_html', 'bundle_loop_show_default_selected_price', 99, 2); function bundle_loop_show_default_selected_price($price_html, $product){ // 仅在前台商店循环、分类页针对捆绑商品生效 if( !is_admin() && (is_shop() || is_product_taxonomy()) && $product->is_type('bundle') ){ // 如果默认勾选组合为最低价组合可直接调用内置方法获取价格 $default_active_price = $product->get_bundle_price('min', true); $default_regular_price = $product->get_bundle_regular_price('min', true); // 格式化价格,兼容促销价显示样式 if( $default_regular_price != $default_active_price ){ $price_html = wc_format_sale_price( wc_price($default_regular_price), wc_price($default_active_price) ) . $product->get_price_suffix(); } else { $price_html = wc_price($default_active_price) . $product->get_price_suffix(); } /* 若默认勾选组合不是最低价组合,注释上述代码,直接调用插件内置方法生成匹配默认配置的价格HTML即可: $price_html = WC_PB_Display::instance()->get_bundle_price_html( $product, array( 'price' => $product->get_default_configuration_price(), 'regular_price' => $product->get_default_configuration_regular_price() ) ); */ } return $price_html; }
代码添加到主题/子主题的
functions.php文件中即可生效,添加前建议提前备份文件避免语法错误导致站点异常。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

