如何在WooCommerce中指定并显示可变产品的最低单价
WooCommerce可变产品最低单包价格展示及后台自定义设置方案
需求背景
站点内的可变产品包含1pack、5pack、10pack和30pack四种规格,其中30pack变体的单包价格最低,需要将该价格展示给访客;同时因每个产品计算方式不同,需在后台添加可手动指定单包价格的设置项。现有代码仅支持简单产品固定除以6计算单包价,无法满足可变产品的需求。
解决方案
1. 添加产品后台自定义设置字段
这段代码会在产品编辑页面的「产品数据」→「定价」面板下添加自定义字段,支持管理员手动指定单包价格:
// 添加产品后台自定义字段 add_action( 'woocommerce_product_options_pricing', 'add_custom_unit_price_field' ); function add_custom_unit_price_field() { woocommerce_wp_text_input( array( 'id' => '_custom_unit_price', 'label' => __( '自定义单包价格', 'woocommerce' ), 'placeholder' => __( '留空则自动计算30pack的单包价', 'woocommerce' ), 'desc_tip' => 'true', 'description' => __( '手动设置后将优先使用此价格作为单包展示价;留空则自动获取30pack变体的单包价格。', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array( 'step' => '0.01', 'min' => '0' ) ) ); } // 保存自定义字段值 add_action( 'woocommerce_admin_process_product_object', 'save_custom_unit_price_field' ); function save_custom_unit_price_field( $product ) { if ( isset( $_POST['_custom_unit_price'] ) ) { $product->update_meta_data( '_custom_unit_price', wc_clean( $_POST['_custom_unit_price'] ) ); } }
2. 修改价格显示逻辑(兼容可变/简单产品)
替换原有的价格过滤器代码,实现优先读取自定义价格、自动计算30pack单包价的功能,同时在产品页、分类页、标签页展示组合价与单包价:
add_filter( 'woocommerce_get_price_html', 'display_unit_price_for_products', 10, 2 ); function display_unit_price_for_products( $price, $product ) { // 仅在产品页面、分类页面、标签页面生效 if ( ! ( is_product() || is_product_category() || is_product_tag() ) ) { return $price; } $group_suffix = ' ' . __( 'pack', 'woocommerce' ); $unit_suffix = ' ' . __( '(per pack)', 'woocommerce' ); $custom_unit_price = $product->get_meta( '_custom_unit_price' ); $unit_price = false; // 处理可变产品 if ( $product->is_type( 'variable' ) ) { // 优先使用自定义单包价 if ( ! empty( $custom_unit_price ) && $custom_unit_price > 0 ) { $unit_price = wc_get_price_to_display( $product, array( 'price' => $custom_unit_price ) ); } else { // 遍历变体,找到30pack规格并计算单包价 foreach ( $product->get_available_variations() as $variation ) { foreach ( $variation['attributes'] as $attr_key => $attr_value ) { if ( strpos( $attr_key, 'pack' ) !== false && $attr_value === '30pack' ) { $variation_price = $variation['display_price']; $unit_price = $variation_price / 30; break 2; // 找到目标变体后退出双层循环 } } } } } else { // 处理简单产品 if ( ! empty( $custom_unit_price ) && $custom_unit_price > 0 ) { $unit_price = wc_get_price_to_display( $product, array( 'price' => $custom_unit_price ) ); } else { // 可根据简单产品包装规格调整除数,此处保留原逻辑的除以6 $unit_price = $product->get_price() / 6; $unit_price = wc_get_price_to_display( $product, array( 'price' => $unit_price ) ); } } // 生成最终价格展示HTML if ( $unit_price ) { $unit_price_html = wc_price( $unit_price ) . $unit_suffix; // 处理产品促销状态 if ( $product->is_on_sale() ) { $group_price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ) ) . $group_suffix; } else { $group_price_html = $price . $group_suffix; } $price = $group_price_html . '<br>' . $unit_price_html; } return $price; }
使用说明
- 将两段代码添加到主题的
functions.php文件,或通过代码片段插件导入 - 编辑产品时,在「产品数据」→「定价」标签下设置「自定义单包价格」:
- 手动输入数值:将优先展示该价格作为单包价
- 留空:系统自动查找30pack变体价格并计算单包价
- 简单产品的默认计算逻辑为价格除以6,可根据实际包装规格修改代码中对应除数
内容的提问来源于stack exchange,提问作者Klaark Kent
相关产品推荐
相关产品推荐

