如何将ACF位置下拉选择字段的值保存至WordPress Dokan产品发布页
代码错误排查与修正方案
现有代码的核心硬伤
- 前端下拉渲染的手滑错误:你写option标签的时候,value属性里多拼了一个多余的
.,对应代码行是echo'<option class="level-0" value=.'.$k.'>' . $v . '</option>';。等于每个选项的提交值都硬加了个前置点号,比如本来选项的键是city_center,实际提交给后端的是.city_center,和ACF字段本身定义的选项值完全不匹配,就算存进去也对不上。 - 存储逻辑的键名错位:你保存的时候用
update_post_meta自己造了个plocation的meta键存值,但ACF的选择字段是认自己注册的字段名的,你现在等于把值存到了一个产品页根本不识别的独立自定义字段里。前端编辑页加载的时候,ACF会读自己存的那份字段值,自然一直显示默认选中状态,根本看不到你存的那个零散的meta值。 - 编辑场景缺失回显逻辑:原来的下拉渲染代码没有读取当前产品已保存的字段值给对应option加selected标记,哪怕字段值存对了,打开编辑页的时候下拉框还是会默认跳到第一个选项,看起来就像值根本没存上。
- 空值场景没处理:代码里写了只有
plocation非空才执行存储,遇到用户选默认“请选择位置”的情况就直接跳过,旧的字段值会一直留着,没法清空。
修正后的可用代码
1. 下拉框前端展示代码
add_action( 'dokan_new_product_after_product_tags','new_product_field',5); function new_product_field(){ $field_key = "field_601141959f1ad"; $field = get_field_object($field_key); if( $field ) { global $post; // 读取当前产品已保存的选中值,用于编辑时回显 $selected_val = get_post_meta($post->ID, $field['name'], true); echo '<div class="acf-task-difficulty-values">'; echo '<select class="dokan-form-control" name="plocation">'; echo '<option value="0">–Select a location–</option>'; foreach( $field['choices'] as $k => $v ) { // 给匹配的选项加上选中标记 $selected = ($k == $selected_val) ? 'selected' : ''; echo '<option class="level-0" value="'.$k.'" '.$selected.'>' . $v . '</option>'; } echo '</select>'; echo '</div><br>'; } }
2. 保存逻辑代码(对接ACF官方存储规则)
add_action( 'dokan_new_product_added','save_loc', 10, 2 ); add_action( 'dokan_product_updated', 'save_loc', 10, 2 ); function save_loc($product_id, $postdata){ if ( ! dokan_is_user_seller( get_current_user_id() ) ) { return; } $field_key = "field_601141959f1ad"; $input_val = isset($postdata['plocation']) ? sanitize_text_field($postdata['plocation']) : ''; // 空值/默认值场景直接清空ACF字段 if ( empty($input_val) || $input_val == '0' ) { update_field($field_key, '', $product_id); } else { // 走ACF原生存储逻辑,和后台产品编辑页的存储逻辑完全一致 update_field($field_key, $input_val, $product_id); } }
上线后验证方式
修改完代码提交保存后,重新在前端Dokan发布/编辑产品,选个非默认值保存,再回编辑页看下拉框是否正常回显选中值,同时去后台产品编辑页看对应ACF字段的选中状态是否和前端保持一致。
注:如果之前测试时已经存过一堆
plocation开头的冗余自定义字段,去后台自定义字段列表里删掉就行,不影响新逻辑运行。
内容的提问来源于stack exchange,提问作者ashen990
相关产品推荐
相关产品推荐

