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

如何为自定义文章类型仅返回指定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 ) );
                                    }
                            }
                        )
                ) 
        )
    );
});

解决方案

核心思路

  1. 先在路由配置中声明允许接收的额外字段参数(或用批量字段参数)
  2. 在回调函数中判断请求参数,动态构建要返回的字段列表
  3. 根据字段列表从文章数据中提取对应内容返回

方式一:指定单个字段参数(适合固定几个常用字段)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:45:39