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

前端使用acf_form时如何展示WooCommerce商品字段与元数据

问题背景

我正在使用ACF搭建前端表单,供供应商角色用户提交商品,表单提交后会自动生成全新的WooCommerce商品。

当前使用的表单配置代码如下:

$options = array(
    'post_id' => 'new_post',
    'post_title' => true,
    'post_content' => true,
    'new_post'      => array(
        'post_type'       => 'product',
        'post_status'     => 'draft'
    ),
    'field_groups' => [$my_field_group_id_created_in_acf],
    'form' => true,
    'return' => '%post_url%',
    'html_submit_button'    => '<input type="submit" value="%s" />',
    'updated_message' => 'Product Created',
    'submit_value' => 'Submit Product'
);

acf_form($options);

目前表单默认只输出标题字段、内容编辑器、自行配置的ACF字段组内容,WooCommerce原生的价格、促销价、商品分类、标签这类核心商品字段,还有非ACF创建的自定义元字段都不会自动加载显示。


解决方案

acf_form() 默认只会渲染ACF自身注册的字段、以及手动开启的post_title/post_content这类基础文章字段,不会自动拉取WooCommerce的商品元字段,分两步处理即可实现需求:

1. 手动在表单中插入需要的原生/自定义字段

可以通过ACF提供的位置钩子,在ACF字段输出的对应位置插入非ACF字段,常用两个钩子:

  • acf/form/before_fields:在所有ACF字段之前输出内容
  • acf/form/after_fields:在所有ACF字段之后、提交按钮之前输出内容

举个例子,插入常规售价、促销价、商品分类下拉、商品标签输入框的代码可以直接放到主题的functions.php中:

// 在ACF表单末尾追加WooCommerce原生商品字段
add_action('acf/form/after_fields', function() {
    // 替换成你商品提交表单所在页面的ID,避免影响其他页面的ACF表单
    if (!is_page(123)) return;
    $regular_price = isset($_POST['_regular_price']) ? sanitize_text_field($_POST['_regular_price']) : '';
    $sale_price = isset($_POST['_sale_price']) ? sanitize_text_field($_POST['_sale_price']) : '';
    ?>
    <div class="acf-field acf-field-number">
        <div class="acf-label">
            <label for="_regular_price">常规售价</label>
        </div>
        <div class="acf-input">
            <input type="number" step="0.01" name="_regular_price" id="_regular_price" value="<?php echo esc_attr($regular_price); ?>">
        </div>
    </div>
    <div class="acf-field acf-field-number">
        <div class="acf-label">
            <label for="_sale_price">促销价</label>
        </div>
        <div class="acf-input">
            <input type="number" step="0.01" name="_sale_price" id="_sale_price" value="<?php echo esc_attr($sale_price); ?>">
        </div>
    </div>
    <div class="acf-field acf-field-taxonomy">
        <div class="acf-label">
            <label for="product_cat">商品分类</label>
        </div>
        <div class="acf-input">
            <?php
            wp_dropdown_categories([
                'taxonomy' => 'product_cat',
                'name' => 'product_cat[]',
                'id' => 'product_cat',
                'multiple' => true,
                'hide_empty' => false,
                'hierarchical' => true,
            ]);
            ?>
        </div>
    </div>
    <div class="acf-field acf-field-text">
        <div class="acf-label">
            <label for="product_tags">商品标签</label>
        </div>
        <div class="acf-input">
            <input type="text" name="product_tags" id="product_tags" placeholder="多个标签用英文逗号分隔">
        </div>
    </div>
    <?php
});

其他非ACF创建的自定义元字段,也可以参照上面的HTML结构自行编写input插入到表单对应位置,字段name属性和存储元数据的meta_key保持一致即可。

2. 表单提交后保存自定义字段数据

ACF默认不会处理手动添加的非ACF字段,需要挂载acf/save_post钩子,在文章创建完成后把这些字段的数据存到对应位置,注意优先级要设为20,等ACF完成基础文章创建逻辑后再执行:

add_action('acf/save_post', function($post_id) {
    // 排除后台编辑、其他表单提交场景,只处理前台新建商品的提交
    if (get_post_type($post_id) !== 'product' || is_admin()) return;

    // 保存价格数据
    if (isset($_POST['_regular_price'])) {
        update_post_meta($post_id, '_regular_price', wc_clean(wp_unslash($_POST['_regular_price'])));
    }
    if (isset($_POST['_sale_price'])) {
        update_post_meta($post_id, '_sale_price', wc_clean(wp_unslash($_POST['_sale_price'])));
    }

    // 保存商品分类
    if (isset($_POST['product_cat']) && is_array($_POST['product_cat'])) {
        $cat_ids = array_map('intval', $_POST['product_cat']);
        wp_set_object_terms($post_id, $cat_ids, 'product_cat');
    }

    // 保存商品标签
    if (isset($_POST['product_tags'])) {
        $tags = array_map('trim', explode(',', sanitize_text_field($_POST['product_tags'])));
        wp_set_object_terms($post_id, $tags, 'product_tag');
    }

    // 其他自定义元字段参照同样逻辑存储即可
    // 示例:if (isset($_POST['your_custom_meta_key'])) update_post_meta($post_id, 'your_custom_meta_key', sanitize对应方法处理后的值);

}, 20);

可选简化方案

如果不想手动写字段HTML和保存逻辑,可以直接在ACF中创建和WooCommerce原生字段meta_key同名的字段,比如创建数字类型字段,字段名设为_regular_price,ACF就会自动渲染表单、自动保存对应数据,不需要额外编写钩子。注意WooCommerce的价格类字段meta_key是以下划线开头的,创建ACF字段时不要遗漏前缀。

如果需要添加库存、运费、重量这类其他原生商品字段,只要找到对应的meta_key或者分类法名称,按照上述逻辑添加字段、编写保存逻辑即可,不需要额外安装插件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:31:11