A client is using the WordPress REST JSON API with some WordPress data models. We need to hit the WordPress API from the frontend and retreive a few hundred custom posts.

WordPress has a hard limit of 100 custom posts.

I would like to change this limit to a much higher number for this use case. I read that you cannot monkey patch in PHP.

Is there any way to adjust the per_page->maximum value to, say, 10000?

3 Answers
3

You cannot get over that limit of 100 posts per requests in WordPress for default requests. One way to still retrieve all posts would be to query that interface until you have all posts. Another would be a custom endpoint.

If you can, I suggest creating your own REST endpoint. This will already work and return all posts

add_action('rest_api_init', 'my_more_posts');

function my_more_posts() {
    register_rest_route('myplugin/v1', '/myposts', array(
        'methods' => 'GET',
        'callback' => 'my_more_posts_callback',
    ));
}

function my_more_posts_callback( WP_REST_Request $request ) {
    $args = array(
        'posts_per_page' => -1,
    );
    return get_posts($args);
}

More info on creating your own endpoint can be found here, whereas the arguments of get_posts() are explained here.


For a pure JavaScript solution in the frontend, you can utilize the x-wp-totalpages header which tells the total amount of pages. Unless this page is reached, we know we need to query again. So a basic recursive version like this works:

var allPosts = [];

function retrievePosts(opt) {
  if (typeof opt === 'undefined')
    opt = {};

  var options = $.extend({
    per_page: 100,
    page: 1
  }, opt);
  var url="https://example.com/wp-json/wp/v2/posts";
  var uri = url + '?per_page=" + options.per_page + "&page=" + options.page;

  $.getJSON(uri, function(data, status, jqXHR) {
    var totalpages = jqXHR.getResponseHeader("x-wp-totalpages');

    allPosts = allPosts.concat( data );

    // here the magic happens
    // if we are not done
    if (options.page < totalpages) {
      // request again, but for the next page
      retrievePosts({
        per_page: options.per_page,
        page: options.page + 1
      });
    } else {

      // WE ARE DONE
      // posts are in allPosts

    }
  });
};
retrievePosts();

Leave a Reply

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