如何在WooCommerce单品页显示所有在售商品的优惠金额
WooCommerce 简单/可变商品优惠金额显示方案
问题背景
我目前用以下代码在商品列表页正常显示简单商品和可变商品的折扣百分比:
add_action( 'woocommerce_before_shop_loop_item_title', 'bbloomer_show_sale_percentage_loop', 25 ); function bbloomer_show_sale_percentage_loop() { global $product; if ( !$product->is_on_sale() ) return; if ( $product->is_type( 'simple' ) ) { $max_percentage = ( ( $product->get_regular_price() - $product->get_sale_price() ) / $product->get_regular_price() ) * 100; } elseif ( $product->is_type( 'variable' ) ) { $max_percentage = 0; foreach ( $product->get_children() as $child_id ) { $variation = wc_get_product( $child_id ); $price = $variation->get_regular_price(); $sale = $variation->get_sale_price(); if ( $price != 0 && !empty( $sale ) ) $percentage = ( $price - $sale ) / $price * 100; if ( $percentage > $max_percentage ) { $max_percentage = $percentage; } } } if ( $max_percentage > 0 ) echo "<p class='sale-perc'>" . round( $max_percentage ) . "% Discount</p>"; }
模板调用方式:
<?php bbloomer_show_sale_percentage_loop(); ?>
现在需要实现显示商品优惠金额的功能,找到的代码仅支持简单商品,且添加到functions.php后会导致WooCommerce支付页面崩溃。需要一套支持所有在售商品(简单+可变)的稳定方案。
原简单商品优惠金额代码(存在问题):
add_action( 'woocommerce_single_product_summary', 'simple_product_saving_amount', 11 ); function simple_product_saving_amount() { global $product; if( $product->is_type('simple') && $product->is_on_sale() ) { $regular_price = (float) wc_get_price_to_display( $product, array('price' => $product->get_regular_price() ) ); $active_price = (float) wc_get_price_to_display( $product, array('price' => $product->get_sale_price() ) ); $saved_amount = $regular_price - $active_price; echo '<p id="saving_total_price">'. __("your profit") .': ' . wc_price($saved_amount) . ' </p>';} }
优化后的解决方案
以下代码同时支持简单商品和可变商品,修复了语法错误(避免支付页崩溃),并处理了价格显示的细节:
1. 单商品页面显示优惠金额
add_action( 'woocommerce_single_product_summary', 'display_product_saving_amount', 11 ); function display_product_saving_amount() { global $product; // 非在售商品直接返回 if ( !$product->is_on_sale() ) return; $saved_amount = 0; // 处理简单商品 if ( $product->is_type('simple') ) { $regular_price = (float) wc_get_price_to_display( $product, array('price' => $product->get_regular_price()) ); $sale_price = (float) wc_get_price_to_display( $product, array('price' => $product->get_sale_price()) ); $saved_amount = $regular_price - $sale_price; } // 处理可变商品(取最大优惠金额) elseif ( $product->is_type('variable') ) { foreach ( $product->get_children() as $child_id ) { $variation = wc_get_product( $child_id ); if ( !$variation->is_on_sale() ) continue; $reg_price = (float) wc_get_price_to_display( $variation, array('price' => $variation->get_regular_price()) ); $sale_price = (float) wc_get_price_to_display( $variation, array('price' => $variation->get_sale_price()) ); if ( $reg_price > 0 && $sale_price > 0 ) { $current_saving = $reg_price - $sale_price; if ( $current_saving > $saved_amount ) { $saved_amount = $current_saving; } } } } // 仅当有优惠金额时显示 if ( $saved_amount > 0 ) { echo '<p class="saving-amount">'. __('最高节省', 'woocommerce') .': ' . wc_price($saved_amount) . '</p>'; } }
2. 商品列表页显示优惠金额(可选)
如果需要在列表页也显示优惠金额,可添加以下代码:
add_action( 'woocommerce_before_shop_loop_item_title', 'display_loop_saving_amount', 30 ); function display_loop_saving_amount() { global $product; if ( !$product->is_on_sale() ) return; $saved_amount = 0; if ( $product->is_type('simple') ) { $regular_price = (float) wc_get_price_to_display( $product, array('price' => $product->get_regular_price()) ); $sale_price = (float) wc_get_price_to_display( $product, array('price' => $product->get_sale_price()) ); $saved_amount = $regular_price - $sale_price; } elseif ( $product->is_type('variable') ) { foreach ( $product->get_children() as $child_id ) { $variation = wc_get_product( $child_id ); if ( !$variation->is_on_sale() ) continue; $reg_price = (float) wc_get_price_to_display( $variation, array('price' => $variation->get_regular_price()) ); $sale_price = (float) wc_get_price_to_display( $variation, array('price' => $variation->get_sale_price()) ); if ( $reg_price > 0 && $sale_price > 0 ) { $current_saving = $reg_price - $sale_price; if ( $current_saving > $saved_amount ) { $saved_amount = $current_saving; } } } } if ( $saved_amount > 0 ) { echo '<span class="loop-saving-amount">'. __('省', 'woocommerce') . wc_price($saved_amount) .'</span>'; } }
关键修复点
- 修复了原代码中的引号转义错误(
"替换为标准双引号),避免语法错误导致页面崩溃 - 增加了空值判断(如检查子产品是否在售、价格是否有效),防止计算时出现异常
- 统一使用
wc_get_price_to_display()获取前端显示价格,自动适配WooCommerce的价格设置(如含税/不含税) - 支持可变商品,取所有变体中的最大优惠金额展示
使用说明
- 将代码添加到你的WordPress子主题的
functions.php文件中(避免主题更新丢失代码) - 可根据需求调整钩子的优先级(代码中的数字,如
11、30),控制显示位置 - 可通过CSS自定义
.saving-amount或.loop-saving-amount的样式
内容的提问来源于stack exchange,提问作者user21540512
相关产品推荐
相关产品推荐

