Some time ago, after announcing the WordPress 5.1 first beta on the WordPress Brasil Facebook group, a user asked when we’d have the option to random order the posts on WordPress REST API. I explained that core doesn’t need to allow it because it could be done through a custom code.
The code below uses the filter rest_{$this->post_type}_collection_params
to include rand
as an entry of the array which enumerates the possible values for ordination. This filter is used in the end of the get_collection_params
method, inside the WP_REST_Posts_Controller
class, as you can see here. The {$this->post_type}
filter part is variable and in the code I used it to change the posts list.
In order to apply the random order, you only have to call /wp-json/wp/v2/posts?orderby=rand
. If you’re using some cache solution, the final result can be affected.
<?php
/**
* Plugin Name: REST API - Post list randomize
* Description: Randomize the content list in REST API passing `orderby=rand` as parameter.
* Version: 1.0.0
* Author: Felipe Elia | Codeable
* Author URI: https://codeable.io/developers/felipe-elia?ref=qGTOJ
*/
/**
* Add `rand` as an option for orderby param in REST API.
* Hook to `rest_{$this->post_type}_collection_params` filter.
*
* @param array $query_params Accepted parameters.
* @return array
*/
function add_rand_orderby_rest_post_collection_params( $query_params ) {
$query_params['orderby']['enum'][] = 'rand';
return $query_params;
}
add_filter( 'rest_post_collection_params', 'add_rand_orderby_rest_post_collection_params' );
You only have to save the code as a PHP file and put it into the plugins directory. The code is also available as a gist.
If you have any trouble deploying this code or with anything related to WordPress, give a look at my Codeable Profile and click on that Hire button!
Esto se puede aplicar para ordenar eventos con el plugin WP Events Manager a traves del Api Rest?
Hi Lorenzo. I’ve never used WP Events Manager but it doesn’t seem their post types are even available through the REST API, right? But if it is, yeah, probably you can apply a similar version of this code to achieve that. Good luck!
Great plugin which works as an independent filter, however it does not appear to work with the category filter.
/wp-json/wp/v2/posts?categories=10?orderby=rand
Produces this
{
“code”: “rest_invalid_param”,
“message”: “Invalid parameter(s): categories”,
“data”: {
“status”: 400,
“params”: {
“categories”: “categories[0] is not of type integer.”
}
}
}
However categories is an official filter. Is there something I am missing?
Thanks
Mark
Hey Mark! You should have a “&” between the parameters, not a “?”, so it should be:
/wp-json/wp/v2/posts?categories=10&orderby=rand
and not
/wp-json/wp/v2/posts?categories=10?orderby=rand
Can you give it a try and let me know if it works? Thanks!
Hi Felipe
Thanks for that I don’t know why I didn’t spot it 😀
Great stuff it works 🙂
Thank you
Mark
The above snippet once worked perfect in my project. About 2 weeks ago, it was suddenly broken. I didn’t modify any code in my project at that time. Looks like WordPress API updates something. I tried to find any docs about recent updates in WordPress but found nothing related to the orderby parameters.
I used Postman to test. It will respond as:
{
“code”: “rest_invalid_param”,
“message”: “Invalid parameter(s): orderby”,
“data”: {
“status”: 400,
“params”: {
“orderby”: “orderby is not one of author, date, id, include, modified, parent, relevance, slug, include_slugs, title.”
}
}
}
I tried to print out the result of $query_params after adding ‘rand’. It can show the rand was indeed added:
Array
(
[0] => author
[1] => date
[2] => id
[3] => include
[4] => modified
[5] => parent
[6] => relevance
[7] => slug
[8] => include_slugs
[9] => title
[10] => rand
)
From the above result in my test, I think something wrong happened when the returned $query_params registers back to WordPress.
I also manually added ‘rand’ where orderby parameters locate in the file class-wp-rest-posts-controller.php:
$query_params[‘orderby’] = array(
‘description’ => __( ‘Sort collection by object attribute.’ ),
‘type’ => ‘string’,
‘default’ => ‘date’,
‘enum’ => array(
‘author’,
‘date’,
‘id’,
‘include’,
‘modified’,
‘parent’,
‘relevance’,
‘slug’,
‘include_slugs’,
‘title’
),
);
Then orderby=rand can work properly. But using add_filter function cannot add ‘rand’ into the enum array correctly.
Can you give me some clues what’s happened recently in WordPress that make the useful method becomes unavailable suddenly? Thanks!
I’ve just tested the snippet with a fresh 5.3.2 install and it worked. Are you trying to order “posts” or another post type? If so, are you changing the filter name properly?
Thanks Felipe. Just like you said, I want to order a customized type “questions” created by ACF. So I need to change the filter name as “rest_questions_collection_params”.
Just no ideas why it didn’t need to change before but suddenly has this requirement now. But anyway, since it’s solved, just don’t bother. My project is more front-end. WP is just storage. Thanks again.