WordPress REST API order by meta_value

Another quick tip here, for future reference.

I needed to sort the custom posts in a REST API response by a meta value, something like this:

https://www.timrosswebdevelopment.com/wp-json/wp/v2/accommodation?orderby=number_of_beds

Where number_of_beds is a field that has been added using Advance Custom Fields.

The problem is the REST API only allows certain core fields to be used for the orderby param. See my other post on adding REST API orderby custom values for more info. So the question was how to add another.

The answer came as usual on StackExchange, from here, and here. But only properly understood it after I read through the discussion a WordPress ticket.

By making use of a filters specific to my custom post type, I can set the correct query arg in the WP_Query, which makes the results return in the correct order.

Then, to orderby a meta_value, the WP_Query needs to have two values, the orderby=meta_value and also needs to have the meta_key=number_of_beds so the query knows which meta value to look at. The filter I used to achieve this is rest_{$this->post_type}_query. I look for the orderby param on the request and then set the value correctly in the query args.

<?php
/**
* Check the orderby param for the particular REST API for hte custom post type.
* If it is set to a particular meta_ket, then set the orderby and meta_key query args/
* @link https://www.timrosswebdevelopment.com/wordpress-rest-api-order-by-meta_value/
*/
function filter_rest_accommodation_query($query_vars, $request) {
$orderby = $request->get_param('orderby');
if (isset($orderby) && $orderby === 'number_of_beds') {
$query_vars["orderby"] = "meta_value_num";
$query_vars["meta_key"] = "number_of_beds";
}
return $query_vars;
}
// The filter is named rest_{post_type}_query. So you need to hook a new filter for each
// of the custom post types you need to sort.
add_filter( 'rest_accommodation_query', 'filter_rest_accommodation_query', 10, 2);
?>

In this example, I’m using meta_value_num because the value is actually a number stored as a string, so the orderby needs to take that in to account. Check out the WP_Query docs for more info on that.

NB. I originally tried to do this directly in the REST API request, like this:

https://www.timrosswebdevelopment.com/wp-json/wp/v2/accommodation?orderby=meta_value_num&meta_key=number_of_beds

But the meta_key parameter was removed and didn’t make it in to the query args. The way I have discussed was the easiest way I found to implement, only affecting one custom post type.

3 thoughts on “WordPress REST API order by meta_value

  1. This worked a treat, thanks! I’m retrieving events from a shared calendar so I made 2 minor mods: no need for parameter as I always want to sort by start date; needed to add “order” query_var as it defaults to “DESC”.

    // order REST API results by sort date
    // the filter is named rest_{post_type}_query.
    // props @link https://www.timrosswebdevelopment.com/wordpress-rest-api-order-by-meta_value/
    add_filter( ‘rest_event_query’, function ( $query_vars, $request ) {
    $query_vars[‘orderby’] = ‘meta_value’;
    $query_vars[‘meta_key’] = ‘event_start_date’;
    $query_vars[‘order’] = ‘ASC’;
    return $query_vars;
    }, 10, 2);

  2. This just returns an error for me.
    rest_invalid_param Invalid parameter(s): orderby
    orderby is not one of author, date, id, include, modified, parent, relevance, slug, include_slugs, title, menu_order.

    1. Hi John, I use the above code in one of my sites and it’s working fine. without seeing your code, it’s hard to know if there’s a problem with your implementation. Can you post below what you’ve got?

Leave a Reply

Your email address will not be published. Required fields are marked *