You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce产品变体多选字段:无法保存及前端展示求助

解决WooCommerce产品变体多选季节选项的保存与展示问题

我帮你梳理了完整的解决方案,分两步搞定:先让多选选项能正常保存,再在单产品页面动态展示选中的季节。直接把下面的代码添加到你主题的functions.php文件里,或者用自定义代码插件(比如Code Snippets)来添加,避免主题更新丢失代码。

第一步:添加并保存季节多选字段

这部分代码会在产品变体的编辑界面添加春夏秋冬的多选选项,并且处理保存逻辑,确保选中的选项能被存下来。

// 在产品变体编辑界面添加季节多选字段
add_action( 'woocommerce_product_after_variable_attributes', 'add_season_availability_variation_field', 10, 3 );
function add_season_availability_variation_field( $loop, $variation_data, $variation ) {
    // 获取已保存的季节选项(如果有的话)
    $saved_seasons = get_post_meta( $variation->ID, '_season_availability', true );
    $saved_seasons = !empty( $saved_seasons ) ? explode( ',', $saved_seasons ) : array();

    echo '<div class="options_group">';
    // 隐藏主复选框,我们用自定义的多选列表
    woocommerce_wp_checkbox( array(
        'id'            => '_season_availability[' . $loop . ']',
        'label'         => __( '供应季节', 'woocommerce' ),
        'description'   => __( '选择该苗木可供应的季节', 'woocommerce' ),
        'custom_attributes' => array( 'style' => 'display:none;' ),
    ) );

    // 定义季节选项
    $seasons = array(
        'spring'  => __( '春季', 'woocommerce' ),
        'summer'  => __( '夏季', 'woocommerce' ),
        'autumn'  => __( '秋季', 'woocommerce' ),
        'winter'  => __( '冬季', 'woocommerce' ),
    );

    // 输出多选选项列表
    echo '<div style="margin-top:10px;">';
    foreach ( $seasons as $key => $label ) {
        echo '<label style="display:inline-block; margin-right:15px;">';
        echo '<input type="checkbox" name="season_availability[' . $loop . '][]" value="' . esc_attr( $key ) . '" ' . checked( in_array( $key, $saved_seasons ), true, false ) . '>';
        echo esc_html( $label );
        echo '</label>';
    }
    echo '</div>';
    echo '</div>';
}

// 保存产品变体的季节多选字段
add_action( 'woocommerce_save_product_variation', 'save_season_availability_variation_field', 10, 2 );
function save_season_availability_variation_field( $variation_id, $i ) {
    if ( isset( $_POST['season_availability'][$i] ) ) {
        // 清理输入数据,转成逗号分隔的字符串存储
        $seasons = array_map( 'sanitize_text_field', $_POST['season_availability'][$i] );
        update_post_meta( $variation_id, '_season_availability', implode( ',', $seasons ) );
    } else {
        // 如果没有选中任何选项,清空对应的元数据
        delete_post_meta( $variation_id, '_season_availability' );
    }
}

第二步:在单产品页面展示选中的季节

这部分代码会在单产品页面添加一个展示区域,对于可变产品,用户切换不同变体时,会自动更新显示对应的供应季节;对于简单产品则直接显示。

// 在单产品页面添加季节展示容器,并准备变体数据
add_action( 'woocommerce_single_product_summary', 'add_season_availability_display', 25 );
function add_season_availability_display() {
    global $product;

    if ( $product->is_type( 'variable' ) ) {
        // 收集所有变体的季节数据
        $variation_seasons = array();
        foreach ( $product->get_available_variations() as $variation ) {
            $season_str = get_post_meta( $variation['variation_id'], '_season_availability', true );
            $variation_seasons[$variation['variation_id']] = !empty( $season_str ) ? explode( ',', $season_str ) : array();
        }

        // 季节名称映射(英文转中文)
        $season_labels = array(
            'spring' => '春季',
            'summer' => '夏季',
            'autumn' => '秋季',
            'winter' => '冬季',
        );

        // 输出展示容器
        echo '<div class="season-availability-container" style="margin:15px 0; padding:10px; border:1px solid #eee;">';
        echo '<strong>' . __( '供应季节:', 'woocommerce' ) . '</strong>';
        echo '<span class="season-availability-text">' . __( '请选择产品规格', 'woocommerce' ) . '</span>';
        echo '</div>';

        // 将变体季节数据传给前端JS
        wp_localize_script( 'wc-add-to-cart-variation', 'variationSeasons', array(
            'data' => $variation_seasons,
            'labels' => $season_labels,
        ) );
    } elseif ( $product->is_type( 'simple' ) ) {
        // 简单产品直接读取并显示季节
        $season_str = get_post_meta( $product->get_id(), '_season_availability', true );
        if ( !empty( $season_str ) ) {
            $seasons = explode( ',', $season_str );
            $season_labels = array(
                'spring' => '春季',
                'summer' => '夏季',
                'autumn' => '秋季',
                'winter' => '冬季',
            );
            $display_seasons = array();
            foreach ( $seasons as $season ) {
                $display_seasons[] = isset( $season_labels[$season] ) ? $season_labels[$season] : ucfirst( $season );
            }
            echo '<div class="season-availability-container" style="margin:15px 0; padding:10px; border:1px solid #eee;">';
            echo '<strong>' . __( '供应季节:', 'woocommerce' ) . '</strong>';
            echo implode( '、', $display_seasons );
            echo '</div>';
        }
    }
}

// 添加JS监听变体选择,动态更新季节显示
add_action( 'wp_footer', 'season_availability_js' );
function season_availability_js() {
    global $product;
    if ( $product->is_type( 'variable' ) ) {
        ?>
        <script>
            jQuery(document).ready(function($) {
                // 用户选中有效变体时更新季节显示
                $('form.variations_form').on('show_variation', function(event, variation) {
                    var seasonData = variationSeasons.data[variation.variation_id];
                    var seasonLabels = variationSeasons.labels;
                    var displayText = '';
                    if (seasonData.length > 0) {
                        // 把英文季节转成中文显示
                        var displaySeasons = seasonData.map(function(season) {
                            return seasonLabels[season] || season.charAt(0).toUpperCase() + season.slice(1);
                        });
                        displayText = displaySeasons.join('、');
                    } else {
                        displayText = '无指定供应季节';
                    }
                    $('.season-availability-text').text(displayText);
                });

                // 取消选择变体时重置文本
                $('form.variations_form').on('hide_variation', function() {
                    $('.season-availability-text').text('请选择产品规格');
                });
            });
        </script>
        <?php
    }
}

注意事项

  1. 如果你不需要中文显示,可以把代码里的季节标签改成英文(比如把'春季'改成'Spring')。
  2. 样式部分可以根据你的主题自定义,修改season-availability-container的CSS即可。
  3. 建议用Code Snippets插件来添加代码,比直接修改functions.php更安全,不会因为主题更新丢失代码。

内容的提问来源于stack exchange,提问作者Justus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:24:38