3

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?

2
  • Do you need to use this specific WordPress endpoint? If not, you could write a simple wrapper, which requests 100 pages until it is satisfied and returns the complete set
    – kero
    Jul 8, 2017 at 11:52
  • @kero Do you have an example of such a wrapper in Javascript? It would at least solve the issue.
    – robbintt
    Jul 8, 2017 at 15:53

3 Answers 3

1

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();
7
  • I was hoping to avoid making so many requests since each response is small. I will try this alternative Monday morning. Thanks for the detailed javascript!
    – robbintt
    Jul 8, 2017 at 16:37
  • Well you asked for a JavaScript solution .. :) An alternative would be to create your own custom REST endpoint, I will try to add infos about that as well
    – kero
    Jul 8, 2017 at 16:39
  • I think my biggest hangup is the number of requests I have to make to collect all the data using the javascript PAGE/OFFSET style method.
    – robbintt
    Jul 8, 2017 at 16:43
  • @robbintt Please see my edit. If you have access to the backend, adding your own endpoint is quite simple. You can do so in a small custom plugin
    – kero
    Jul 8, 2017 at 16:57
  • 1
    Nice! Lots of good ideas here. I will let you know how it goes.
    – robbintt
    Jul 8, 2017 at 17:32
0

This is still a problem in 2020, so I just edited the Wordpress source code on our server.

https://core.trac.wordpress.org/browser/trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php

In this file if you search for "100" you can easily find the configuration. I changed mine to 500.

I think Wordpress are right that this can cause front-end speed issues, but for those of us running Wordpress as a headless CMS to render another app (static site in our case) this is really annoying that you can't easily edit it.

1
  • Note that edits you make to core files like this will get overwritten when WordPress updates itself (if you're using automatic updates)
    – Rup
    May 23, 2021 at 0:03
0

There is a hook that can manipulate the per page maximum. The dynamic portion of the hook name, $post_type, refers to the post type slug

function increase_per_page_max($params){
    $params['per_page']['maximum'] = 1000;
    return $params;
}

add_filter('rest_{$post_type}_collection_params', 'increase_per_page_max');

Credit to https://wildwolf.name/how-to-increase-per_page-limit-in-wordpress-rest-api/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.