The REST API endpoint “List Posts” (e.g. GET /wp/v2/posts
) does not support filtering the posts by a post meta (or custom field), therefore passing post meta parameters like meta_key
and meta_value
will by default do nothing.
But the rest_<post type>}_query
filter can be used to manually add custom meta queries to the query arguments passed to WP_Query
.
Here’s an example for the core post
type, but validation and sanitization is up to you…
add_filter( 'rest_post_query', 'my_filter_rest_post_query', 10, 2 );
function my_filter_rest_post_query( $args, $request ) {
if ( isset( $request['meta_key'] ) ) {
$args['meta_key'] = $request['meta_key'];
// If the request did not include the meta_value parameter, or that it's a
// null, then we do not set the meta_value argument. Which means, the API
// response would include any posts that have the meta, regardless the value.
if ( isset( $request['meta_value'] ) ) {
$args['meta_value'] = $request['meta_value'];
}
}
return $args;
}
So with that, your Backbone code should now work, but a better option, which makes use of the core validation functions, where validation is by default done automatically for you, is by registering your custom request parameter using the rest_<post type>_collection_params
filter.
Here’s an example where I used a single custom parameter named meta_status
for your status
meta:
add_filter( 'rest_post_collection_params', 'my_filter_rest_post_collection_params' );
function my_filter_rest_post_collection_params( $query_params ) {
$query_params['meta_status'] = array(
'anyOf' => array(
array( 'type' => 'string' ),
array( 'type' => 'null' ), // Allows a real null value.
),
// Your other arguments here.
);
return $query_params;
}
Now the filter callback might look like:
add_filter( 'rest_post_query', 'my_filter_rest_post_query', 10, 2 );
function my_filter_rest_post_query( $args, $request ) {
if ( array_key_exists( 'meta_status', $request->get_params() ) ) {
$args['meta_key'] = 'status';
// I've allowed a null value, therefore, if the meta_value parameter is a
// null, then we do not set the meta_value argument. Which means, the API
// response would include any posts that have the meta, regardless the value.
if ( isset( $request['meta_status'] ) ) {
$args['meta_value'] = $request['meta_status'];
}
}
return $args;
}