WP REST API orderby meta_value

Dan*_*and 3 rest wordpress

需要能够按元值对 REST API 自定义帖子查询的结果进行排序。

这样做有困难。

我已将我的帖子类型提供给 REST API,并且可以按日期、标题等进行排序...

但是当我尝试 Post Meta 时它不起作用。

我添加了以下代码来尝试启用该功能,但默认为按日期排序。

function my_add_meta_vars ($current_vars) {
  $current_vars = array_merge ($current_vars, array('meta_key', 'meta_value'));
  return $current_vars;
}
add_filter ('query_vars', 'my_add_meta_vars');
add_filter ('rest_query_vars', 'my_add_meta_vars');
Run Code Online (Sandbox Code Playgroud)

我的 REST API 查询是

mysite.com/wp-json/wp/v2/hh_equipment?filter[orderby]=meta_value_num&meta_key=equipment_price&order=desc
Run Code Online (Sandbox Code Playgroud)

我已尝试按照此处的说明进行操作,但无济于事。

运行 WordPress 4.8 并尝试在 4.7 上测试无济于事

Oks*_*niv 6

我已经让它与rest_' . $post_type . '_collection_params过滤器和rest_' . $post_type . '_query过滤器一起工作(将 $post_type 更改为所需的帖子类型 slug):

// Add meta your meta field to the allowed values of the REST API orderby parameter
add_filter(
    'rest_' . $post_type . '_collection_params',
    function( $params ) {
        $params['orderby']['enum'][] = 'YOUR_META_KEY';
        return $params;
    },
    10,
    1
);

// Manipulate query
add_filter(
    'rest_' . $post_type . '_query',
    function ( $args, $request ) {
        $order_by = $request->get_param( 'orderby' );
        if ( isset( $order_by ) && 'YOUR_META_KEY' === $order_by ) {
            $args['meta_key'] = $order_by;
            $args['orderby']  = 'meta_value'; // user 'meta_value_num' for numerical fields
        }
        return $args;
    },
    10,
    2
);
Run Code Online (Sandbox Code Playgroud)

第一个过滤器将您的元字段添加到ordeby参数的可能值中,因为默认情况下 REST API 仅支持:作者、日期、id、包含、修改、父、相关性、slug、include_slugs、标题(检查WP REST 中ordeby参数API 手册)

第二个过滤器允许您操作查询,当您在orderby. 在这里,我们需要重置orderby为 'meta_value' 或 'meta_value_num'(在WP Query class description 中阅读有关此内容的更多信息)并将元键设置为您的自定义字段键。


Gna*_*han 3

请参阅下面的方法,我修改了现有的路由以添加一个新的参数条目,该条目验证meta_key允许的值。也不需要以这种方式修改其余查询变量。

add_filter('rest_endpoints', function ($routes) {
    // I'm modifying multiple types here, you won't need the loop if you're just doing posts
    foreach (['some', 'types'] as $type) {
        if (!($route =& $routes['/wp/v2/' . $type])) {
            continue;
        }

        // Allow ordering by my meta value
        $route[0]['args']['orderby']['enum'][] = 'meta_value_num';

        // Allow only the meta keys that I want
        $route[0]['args']['meta_key'] = array(
            'description'       => 'The meta key to query.',
            'type'              => 'string',
            'enum'              => ['my_meta_key', 'another key'],
            'validate_callback' => 'rest_validate_request_arg',
        );
    }

    return $routes;
});
Run Code Online (Sandbox Code Playgroud)

参考:https: //github.com/WP-API/WP-API/issues/2308