求助:让WooCommerce可变产品支持RRP/MSRP自定义价格字段
没问题,我帮你调整代码,让它支持所有WooCommerce产品类型,包括可变产品及其独立变体。下面是修改后的完整代码,我会同步说明关键改动点:
完整修改代码
// 1. 在后台产品主定价区 + 可变产品变体定价区添加MSRP字段 add_action( 'woocommerce_product_options_pricing', 'add_msrp_field' ); add_action( 'woocommerce_variation_options_pricing', 'add_msrp_variation_field', 10, 3 ); function add_msrp_field() { woocommerce_wp_text_input( array( 'id' => 'msrp', 'class' => 'short wc_input_price', 'label' => __( 'RRP / MSRP', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')', 'data_type' => 'price', ) ); } function add_msrp_variation_field( $loop, $variation_data, $variation ) { woocommerce_wp_text_input( array( 'id' => 'msrp[' . $loop . ']', 'class' => 'short wc_input_price', 'label' => __( 'RRP / MSRP', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')', 'data_type' => 'price', 'value' => get_post_meta( $variation->ID, 'msrp', true ) ) ); } // 2. 保存主产品 + 可变产品变体的MSRP数据 add_action( 'save_post_product', 'save_msrp_data' ); function save_msrp_data( $product_id ) { global $pagenow, $typenow; // 基本校验:页面类型、自动保存、权限 if ( 'post.php' !== $pagenow || 'product' !== $typenow ) return; if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( ! current_user_can( 'edit_product', $product_id ) ) return; // 保存主产品的MSRP if ( isset( $_POST['msrp'] ) ) { $msrp_value = wc_format_decimal( $_POST['msrp'] ); update_post_meta( $product_id, 'msrp', $msrp_value ?: '' ); if ( empty( $msrp_value ) ) delete_post_meta( $product_id, 'msrp' ); } // 保存可变产品的变体MSRP $product = wc_get_product( $product_id ); if ( $product->is_type( 'variable' ) && isset( $_POST['variable_post_id'] ) ) { foreach ( $_POST['variable_post_id'] as $index => $variation_id ) { if ( isset( $_POST['msrp'][$index] ) ) { $variation_msrp = wc_format_decimal( $_POST['msrp'][$index] ); update_post_meta( $variation_id, 'msrp', $variation_msrp ?: '' ); if ( empty( $variation_msrp ) ) delete_post_meta( $variation_id, 'msrp' ); } } } } // 3. 前台产品页面显示MSRP(支持所有产品类型) add_action( 'woocommerce_single_product_summary', 'display_msrp_price', 9 ); function display_msrp_price() { global $product; // 处理简单/分组/外部产品:直接显示主MSRP if ( ! $product->is_type( 'variable' ) ) { $msrp = get_post_meta( $product->get_id(), 'msrp', true ); if ( $msrp ) { echo '<div class="woocommerce_msrp">'; _e( 'RRP / MSRP: ', 'woocommerce' ); echo '<span class="msrp-price">' . wc_price( $msrp ) . '</span>'; echo '</div>'; } return; } // 处理可变产品:先显示主MSRP,再准备变体MSRP的切换逻辑 $main_msrp = get_post_meta( $product->get_id(), 'msrp', true ); echo '<div class="woocommerce_msrp">'; _e( 'RRP / MSRP: ', 'woocommerce' ); echo '<span class="msrp-price">' . ( $main_msrp ? wc_price( $main_msrp ) : '-' ) . '</span>'; echo '</div>'; // 存储所有变体的MSRP数据,用于JS实时切换 $variation_msrps = array(); foreach ( $product->get_available_variations() as $variation ) { $variation_msrp = get_post_meta( $variation['variation_id'], 'msrp', true ); $variation_msrps[$variation['variation_id']] = $variation_msrp ? wc_price( $variation_msrp ) : '-'; } if ( ! empty( $variation_msrps ) ) { ?> <script> jQuery(document).ready(function($) { // 监听变体切换事件 $('form.variations_form').on('show_variation', function(event, variation) { var msrpHtml = '<?php echo esc_js( $main_msrp ? wc_price( $main_msrp ) : '-' ); ?>'; if ( typeof variation.msrp !== 'undefined' ) { msrpHtml = variation.msrp; } $('.woocommerce_msrp .msrp-price').html(msrpHtml); }); // 重置为默认MSRP $('form.variations_form').on('hide_variation', function() { $('.woocommerce_msrp .msrp-price').html('<?php echo esc_js( $main_msrp ? wc_price( $main_msrp ) : '-' ); ?>'); }); }); </script> <?php // 将变体MSRP数据注入到WooCommerce的变体对象中 add_filter( 'woocommerce_available_variation', function( $variation_data, $product, $variation ) use ( $variation_msrps ) { $variation_data['msrp'] = $variation_msrps[$variation->get_id()]; return $variation_data; }, 10, 3 ); } }
关键改动说明
- 后台字段扩展:新增了
woocommerce_variation_options_pricing钩子,给每个可变产品变体单独添加MSRP字段,支持为不同变体设置不同指导价。 - 保存逻辑优化:针对可变产品,遍历所有变体ID,单独保存每个变体的MSRP值;同时保留了主产品MSRP的保存逻辑,当变体未单独设置时,会显示主产品的指导价。
- 前台交互增强:加入了JS监听变体切换事件,用户选择不同变体时,会自动切换显示对应的MSRP;如果变体没有单独设置,则 fallback 到主产品的MSRP。
内容的提问来源于stack exchange,提问作者user11256696
相关产品推荐
相关产品推荐

