WordPress REST API: Enable Random Order of Posts List

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
<?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!

Felipe Elia

Associate Director of Platform Engineering na 10up, WordPress Core Contributor, Global Polyglots Mentor na comunidade internacional do WordPress e Locale Manager na comunidade WordPress Brasil.

This Post Has 8 Comments

  1. Lorenzo Piñango

    Esto se puede aplicar para ordenar eventos con el plugin WP Events Manager a traves del Api Rest?

    1. Felipe Elia

      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!

  2. Mark Ford

    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

    1. Felipe Elia

      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!

      1. Mark Ford

        Hi Felipe
        Thanks for that I don’t know why I didn’t spot it 😀
        Great stuff it works 🙂
        Thank you
        Mark

  3. Jerry Zhang

    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!

    1. Felipe Elia

      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?

      1. Jerry

        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.

Comments are closed.