WooCommerce可变产品添加并显示单价字段问题排查
WooCommerce可变产品单份单价显示修复
原代码问题分析
- 元数据获取错误:显示函数中用
$product->get_id()(父产品ID)读取_price_per_unit,但该字段实际存储在变体(子产品)ID下,父产品无此值,导致无法显示。 - 钩子覆盖不全:仅修改可变产品的价格范围钩子,未处理用户选择变体后显示的单个变体价格。
修复后的完整代码
// 为产品变体添加自定义单份价格字段 function add_price_per_unit_field_variation($loop, $variation_data, $variation) { woocommerce_wp_text_input(array( 'id' => '_price_per_unit[' . $variation->ID . ']', 'label' => __('变体 ' . $loop . ' 单份价格', 'woocommerce'), 'placeholder' => '', 'desc_tip' => 'true', 'description' => __('输入该变体的单份单价。', 'woocommerce'), 'value' => get_post_meta($variation->ID, '_price_per_unit', true), 'type' => 'number', // 改为数字类型,适配价格输入场景 'custom_attributes' => array( 'step' => '0.01', 'min' => '0' ) )); } add_action('woocommerce_variation_options_pricing', 'add_price_per_unit_field_variation', 10, 3); // 保存变体的单份价格字段 function save_price_per_unit_field_variation($variation_id, $i) { if (isset($_POST['_price_per_unit'][$variation_id])) { $price_per_unit = sanitize_text_field($_POST['_price_per_unit'][$variation_id]); update_post_meta($variation_id, '_price_per_unit', $price_per_unit); } } add_action('woocommerce_save_product_variation', 'save_price_per_unit_field_variation', 10, 2); // 修改可变产品的价格范围显示为单份价格范围 function display_variable_price_per_unit($price, $product) { if (!$product->is_type('variable')) { return $price; } $price_per_units = array(); // 遍历所有变体收集单份价格 foreach ($product->get_available_variations() as $variation) { $ppu = get_post_meta($variation['variation_id'], '_price_per_unit', true); if (!empty($ppu)) { $price_per_units[] = (float)$ppu; } } if (!empty($price_per_units)) { $min_ppu = min($price_per_units); $max_ppu = max($price_per_units); if ($min_ppu === $max_ppu) { return wc_price($min_ppu) . ' 每份'; } else { return wc_price($min_ppu) . ' - ' . wc_price($max_ppu) . ' 每份'; } } return $price; } add_filter('woocommerce_variable_price_html', 'display_variable_price_per_unit', 10, 2); // 修改选中变体后的价格显示为单份价格 function display_variation_price_per_unit($price, $variation) { $price_per_unit = get_post_meta($variation->get_id(), '_price_per_unit', true); if (!empty($price_per_unit)) { return wc_price($price_per_unit) . ' 每份'; } return $price; } add_filter('woocommerce_variation_price_html', 'display_variation_price_per_unit', 10, 2); add_filter('woocommerce_variation_sale_price_html', 'display_variation_price_per_unit', 10, 2);
代码说明
- 字段优化:将输入框改为数字类型,限制小数步长为0.01,避免非数字输入。
- 保存逻辑优化:增加POST值存在判断,避免无输入时报错。
- 价格范围处理:遍历所有变体收集单份价格,生成统一的价格范围显示。
- 选中变体处理:针对单个变体的价格钩子,替换显示为对应的单份价格。
内容的提问来源于stack exchange,提问作者user22774038
相关产品推荐
相关产品推荐

