如何为自定义文章类型仅返回指定meta_key值而非全部
WordPress REST API 自定义返回字段实现方案
问题背景
我有一个包含40个字段的自定义文章类型,其中osm_geometry是必填请求参数。需要实现以下返回逻辑:
- 当请求仅传入osm_geometry时,返回全部40个字段
- 如果请求中还传入其他参数(比如
name),则只返回osm_geometry和这些指定的字段
原路由代码如下:
add_action('rest_api_init', function(){ register_rest_route('fs/v1', '/fs_ski_resort/', array( 'methods' => 'GET', 'callback' => 'fs_ski_resort_data', 'args' => array( 'osm_geometry' => array( 'required' => true, 'validate_callback' => function($param, $request, $key) { if ( !empty($param) ){ return TRUE; } else { return new WP_Error( 'no_osm_geometry', 'osm_geometry cannot be blank', array( 'status' => 404 ) ); } } ) ) ) ); });
解决方案
核心思路
- 先在路由配置中声明允许接收的额外字段参数(或用批量字段参数)
- 在回调函数中判断请求参数,动态构建要返回的字段列表
- 根据字段列表从文章数据中提取对应内容返回
方式一:指定单个字段参数(适合固定几个常用字段)
add_action('rest_api_init', function(){ register_rest_route('fs/v1', '/fs_ski_resort/', array( 'methods' => 'GET', 'callback' => 'fs_ski_resort_data', 'args' => array( 'osm_geometry' => array( 'required' => true, 'validate_callback' => function($param, $request, $key) { if ( !empty($param) ){ return TRUE; } else { return new WP_Error( 'no_osm_geometry', 'osm_geometry cannot be blank', array( 'status' => 400 ) ); } } ), // 添加允许传入的其他字段,按需扩展 'name' => array( 'required' => false, 'sanitize_callback' => 'sanitize_text_field' ), 'address' => array( 'required' => false, 'sanitize_callback' => 'sanitize_text_field' ) ) )); }); function fs_ski_resort_data($request) { // 获取所有请求参数 $params = $request->get_params(); // 默认返回必填字段osm_geometry $return_fields = array('osm_geometry'); // 过滤掉osm_geometry,剩下的就是用户指定要返回的字段 $extra_fields = array_diff(array_keys($params), array('osm_geometry')); if (!empty($extra_fields)) { $return_fields = array_merge($return_fields, $extra_fields); } else { // 无额外参数时返回全部字段,替换成你获取全部字段的实际逻辑 $post_id = fs_get_post_id_by_geometry($request['osm_geometry']); $all_meta_keys = get_post_custom_keys($post_id); $return_fields = $all_meta_keys; } // 根据osm_geometry获取对应文章ID,替换成你的业务逻辑 $post_id = fs_get_post_id_by_geometry($request['osm_geometry']); if (!$post_id) { return new WP_Error('post_not_found', 'Ski resort not found', array('status' => 404)); } // 提取目标字段数据 $response_data = array(); foreach ($return_fields as $field) { $response_data[$field] = get_post_meta($post_id, $field, true); } return rest_ensure_response($response_data); } // 辅助函数:根据osm_geometry值查找对应文章ID function fs_get_post_id_by_geometry($geometry) { $args = array( 'post_type' => 'fs_ski_resort', // 替换为你的自定义文章类型名 'meta_key' => 'osm_geometry', 'meta_value' => $geometry, 'posts_per_page' => 1, 'fields' => 'ids' ); $posts = get_posts($args); return !empty($posts) ? $posts[0] : false; }
方式二:批量字段参数(灵活支持任意字段)
如果需要更灵活地批量指定返回字段,可以用fields参数接收逗号分隔的字段列表:
add_action('rest_api_init', function(){ register_rest_route('fs/v1', '/fs_ski_resort/', array( 'methods' => 'GET', 'callback' => 'fs_ski_resort_data', 'args' => array( 'osm_geometry' => array( 'required' => true, 'validate_callback' => function($param, $request, $key) { if ( !empty($param) ){ return TRUE; } else { return new WP_Error( 'no_osm_geometry', 'osm_geometry cannot be blank', array( 'status' => 400 ) ); } } ), 'fields' => array( 'required' => false, 'sanitize_callback' => function($value) { // 分割并清理字段名 $fields = explode(',', $value); return array_map('sanitize_text_field', $fields); } ) ) )); }); function fs_ski_resort_data($request) { $params = $request->get_params(); $return_fields = array('osm_geometry'); // 如果传入fields参数,合并到返回字段列表 if (!empty($params['fields'])) { $return_fields = array_merge($return_fields, $params['fields']); $return_fields = array_unique($return_fields); // 去重 } else { // 无指定字段时返回全部字段 $post_id = fs_get_post_id_by_geometry($request['osm_geometry']); $all_meta_keys = get_post_custom_keys($post_id); $return_fields = $all_meta_keys; } // 后续逻辑同方式一 $post_id = fs_get_post_id_by_geometry($request['osm_geometry']); if (!$post_id) { return new WP_Error('post_not_found', 'Ski resort not found', array('status' => 404)); } $response_data = array(); foreach ($return_fields as $field) { $response_data[$field] = get_post_meta($post_id, $field, true); } return rest_ensure_response($response_data); }
注意事项
- 替换代码中的
fs_ski_resort为你的实际自定义文章类型名称 - 如果字段不是存储在
post_meta中,将get_post_meta替换为对应字段的获取方法(比如get_post_field) fs_get_post_id_by_geometry函数需要根据你的数据存储逻辑调整
内容的提问来源于stack exchange,提问作者spreaderman
相关产品推荐
相关产品推荐

