基于表单选项为创建的自定义文章分配自定义分类法
问题描述
使用ACF配合WP User Frontend表单提交生成business-user类型自定义文章,文章生成及字段填充正常。表单包含8个单选选项(每个选项有两个值),需实现:
- 提交表单时,根据用户选择的选项值为文章分配
service自定义分类法 - 用户后续编辑这些选项时,自动更新对应文章的分类法
以下是尝试过但无效的代码:
// Check if it's a custom post type if (get_post_type($post_id) != 'business-user') { // Change 'business-user' to your actual custom post type if different return; } // Define the terms for each radio option and its selections $options_terms = array( 'service_1' => array( // Change 'service_1' to your actual ACF option field name 'Service One' => 'Service One', // Change 'Service One' to the actual value and term you want 'No' => 'No', // Change 'No' to the actual value and term you want ), 'service_2' => array( // Change 'service_2' to your actual ACF option field name 'Service Two' => 'Service Two', // Change 'Service Two' to the actual value and term you want 'No' => 'No', // Change 'No' to the actual value and term you want ), // Continue for other option fields 'service_3' => array( 'Service Three' => 'Service Three', 'No' => 'No', ), 'service_4' => array( 'Service Four' => 'Service Four', 'No' => 'No', ), 'service_5' => array( 'Service Five' => 'Service Five', 'No' => 'No', ), 'service_6' => array( 'Service Six' => 'Service Six', 'No' => 'No', ), 'service_7' => array( 'Service Seven' => 'Service Seven', 'No' => 'No', ), 'service_8' => array( 'Service Eight' => 'Service Eight', 'No' => 'No', ), ); $terms_to_assign = array(); // Iterate through each option field foreach ($options_terms as $option_field => $selections) { // Get the value of the current option field $option_value = get_field($option_field, 'option'); // Ensure 'option' is used for ACF options page fields // Check if the option value exists in the selections array if (array_key_exists($option_value, $selections)) { // Add the corresponding term to the list of terms to assign $terms_to_assign[] = $selections[$option_value]; } } if (!empty($terms_to_assign)) { // Assign the collected terms to the post in the custom taxonomy wp_set_object_terms($post_id, $terms_to_assign, 'service', true); // Change 'your_custom_taxonomy' to your actual custom taxonomy } } add_action('save_post', 'assign_terms_based_on_acf_options'); function update_terms_on_acf_options_change($value, $post_id, $field) { // List of your option fields $option_fields = array( 'service_1', // Change these to your actual ACF option field names 'service_2', 'service_3', 'service_4', 'service_5', 'service_6', 'service_7', 'service_8' ); // Ensure it's one of the option fields if (in_array($field['name'], $option_fields)) { $args = array( 'post_type' => 'business-user', // Change 'business-user' to your actual custom post type 'posts_per_page' => -1, ); $posts = get_posts($args); foreach ($posts as $post) { // Update terms for each post assign_terms_based_on_acf_options($post->ID); } } return $value; } add_filter('acf/update_value', 'update_terms_on_acf_options_change', 10, 3);
原代码问题分析
- 字段获取错误:使用
get_field($option_field, 'option')读取ACF全局选项页字段,但实际这些是单篇文章的自定义字段,应传入$post_id参数 - 分类分配逻辑错误:
wp_set_object_terms第四个参数true为追加模式,多次保存后会导致分类重复累加,应先清空旧分类再添加新分类 - 编辑触发逻辑错误:
update_terms_on_acf_options_change遍历所有business-user文章,实际用户编辑的是单篇文章字段,只需更新当前文章即可 - 缺少安全判断:
save_post钩子未处理自动草稿、修订版本、重复提交等情况,可能导致代码无效重复执行
修正后的代码
function assign_terms_based_on_acf_options($post_id) { // 跳过自动草稿、修订版本、自动保存 if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id) || defined('DOING_AUTOSAVE')) { return; } // 检查是否为目标自定义文章类型 if (get_post_type($post_id) !== 'business-user') { return; } // 定义字段与分类术语slug的映射(确保字段名和术语slug与实际一致) $service_field_term_map = array( 'service_1' => array( 'Service One' => 'service-one', 'No' => 'no-service-1' ), 'service_2' => array( 'Service Two' => 'service-two', 'No' => 'no-service-2' ), 'service_3' => array( 'Service Three' => 'service-three', 'No' => 'no-service-3' ), 'service_4' => array( 'Service Four' => 'service-four', 'No' => 'no-service-4' ), 'service_5' => array( 'Service Five' => 'service-five', 'No' => 'no-service-5' ), 'service_6' => array( 'Service Six' => 'service-six', 'No' => 'no-service-6' ), 'service_7' => array( 'Service Seven' => 'service-seven', 'No' => 'no-service-7' ), 'service_8' => array( 'Service Eight' => 'service-eight', 'No' => 'no-service-8' ), ); $terms_to_assign = array(); foreach ($service_field_term_map as $field_name => $term_map) { // 获取当前文章的字段值 $field_value = get_field($field_name, $post_id); if (!$field_value) continue; // 如果字段值在映射中,添加对应的术语slug if (isset($term_map[$field_value])) { $terms_to_assign[] = $term_map[$field_value]; } } // 替换模式:先移除旧分类,再添加新分类 wp_set_object_terms($post_id, $terms_to_assign, 'service', false); } add_action('save_post', 'assign_terms_based_on_acf_options', 20); // 延迟执行,确保ACF字段已保存 function update_terms_on_acf_field_change($value, $post_id, $field) { // 检查是否为目标字段且文章类型正确 $target_fields = array('service_1', 'service_2', 'service_3', 'service_4', 'service_5', 'service_6', 'service_7', 'service_8'); if (!in_array($field['name'], $target_fields) || get_post_type($post_id) !== 'business-user') { return $value; } // 更新当前文章的分类 assign_terms_based_on_acf_options($post_id); return $value; } add_filter('acf/update_value', 'update_terms_on_acf_field_change', 10, 3);
代码说明
- 安全判断:添加自动草稿、修订版本的跳过逻辑,避免无效执行
- 字段获取修正:使用
get_field($field_name, $post_id)读取当前文章的自定义字段值 - 分类分配优化:使用术语slug(比名称更稳定),通过替换模式清空旧分类再添加新分类,避免重复
- 编辑触发优化:仅在编辑目标字段且当前文章为
business-user类型时,更新当前文章分类,无需遍历所有文章 - 执行时机调整:
save_post钩子设置优先级20,确保ACF字段完成保存后再执行分类分配
内容的提问来源于stack exchange,提问作者WoodyBRUH
相关产品推荐
相关产品推荐

