Wordpress REST API V2 return all posts
Asked Answered
G

12

27

I am missing the function to get ALL the posts (or CPT) by using

example.com/wp-json/wp/v2/country/?per_page=-1

or any similiar. The documentation gives as much info as this:

per_page: Maximum number of items to be returned in result set.

Default: 10

And in another question about the per_page we learn that the allowed range is 1 to 100.

In my case there will be a limited number of posts I need to get, but it will be around 200-300. Are there any workarounds to get them all other than fetching everything page per page and stitching it together?

Additional info if it does matter: I am using angular.js

Gormless answered 1/3, 2016 at 17:3 Comment(0)
H
17

Try this instead for pagination. It returns all the posts on my site.

http://example.com/wp-json/wp/v2/posts/?filter[category_name]=country&filter[posts_per_page]=-1

I get returns above 100 when entered like that and can cap them at 111 etc. http://example.com/wp-json/wp/v2/posts/?filter[category_name]=country&filter[posts_per_page]=111

For the modern WP scenarios the following function will allow you to give returns great than 99.

add_filter( 'rest_post_collection_params', 'big_json_change_post_per_page', 10, 1 );
function big_json_change_post_per_page( $params ) {
    if ( isset( $params['per_page'] ) ) {
        $params['per_page']['maximum'] = 200;
    }
    return $params;
}
Hintze answered 1/3, 2016 at 17:21 Comment(4)
Can anyone confirm this syntax still works? I'm trying it to no avail.Mccullers
You can't get > 100 now but /wp-json/wp/v2/posts/?filter[category_name]=country&per_page=99 got me 99 returned.Hintze
does not work anymore. is there a way to get more than 100?Genocide
returns are now limited to a 100 without writing your own endpoint, otherwise paginating through them is your only optionHintze
C
13

As of WP 4.7 you can increase the upper limit of WP REST API requests by hooking into the following filter:

rest_{$this->post_type}_collection_params

This snippet should do the trick for posts:

add_filter( 'rest_post_query', 'se35728943_change_post_per_page', 10, 2 );

function se35728943_change_post_per_page( $args, $request ) {
    $max = max( (int) $request->get_param( 'custom_per_page' ), 200 );
    $args['posts_per_page'] = $max;    
    return $args;
}

Note: you can not use standard per_page argument (with value more then 100) in request - wp api will respond with error immediately (so the hook will not help). That's in the above code wee use custom_per_page (you can use any another word).

Similar filter for taxonomies: rest_{$this->taxonomy}_query

Example:

add_filter( 'rest_tags_query', 'se35728943_change_terms_per_page', 2, 10 );

function se35728943_change_terms_per_page( $prepared_args, $request ){
    $max = max( 200, (int) $request->get_param( 'custom_per_page' ) );

    $prepared_args['number'] = $max;
    return $prepared_args;
}
Comptom answered 4/4, 2018 at 14:15 Comment(5)
Where should the code for increasing the number of posts that can be retrieved go?Brennen
@Brennen I think the most correct place would be under plugins directory, since it's rather adjustment in logic than presentation (theme).Comptom
To make it a plugin, you could follow this simple guide, which shouldn't take longer than 10-20 minutes to read and implement: webcraft.tools/how-to-create-a-simple-wordpress-pluginComptom
Thanks @Comptom !Brennen
What this does is not increasing the upper allowed limit from 100 to 200, but setting 200 as default limit (instead of 10) and allowing any higher number to be passed in ?custom_per_page. (as it takes bigger of values 200 and the get param) Like it anyway:)O
M
13

The bellow approch worked for me. I was able to retrieve posts from a site with 79 246 posts. I used pagination parameters . Within a loop, from 1 to TotalPages available. See the link for doc.

http://mydomain/wp-json/wp/v2/posts?_embed&per_page=100&page=793

per_page = 100 : means 100 posts max to be retrieved per page

page = 793 : means i have 793 pages with 100 posts per page. the last page had only 46 posts

A loop can then be used in a language of your choice.

Madden answered 11/8, 2018 at 18:30 Comment(1)
What you said here had to be on comment.Fowl
I
12

Couldn't get more than 10 with that syntax. Tried http://example.com/wp-json/wp/v2/posts?per_page=100 and worked up to 100.

Instill answered 14/3, 2018 at 16:7 Comment(0)
P
7

A simpler way that comply with protocol is to collect all responses, in sequence, and perform single setState() call. As follows: (error handling omitted for readability)

componentDidMount() {
    var uri = "http://your-server";
    var totalPages = 0;
    var allResults = [];

    fetch(uri)
    .then(response => {
        totalPages = response.headers.get('X-WP-TotalPages');
        return response.json()})
    .then(results => {
        allResults = results;
        //console.log('Got results from server', results.length); 
        for (let i = 2; i <= totalPages ; i++){
            fetch(uri + "?page=" + i)
            .then(response => {return response.json()})
            .then( moreresults => {
                allResults = allResults.concat( moreresults ); 
            });
        }
        this.setState({responses: allResults });
    });
}
Pesach answered 15/8, 2018 at 0:16 Comment(4)
Answer not helpful, just copy paste of general dataPfister
Thanks for this! I needed a solution that was purely on the client-side.Odelle
Thanks for the X-WP-TotalPages header :)Hydromechanics
@GnanasekaranLoganathan Its my own code. Did not see it anywhere else.Pesach
F
3

In WordPress 4.9.6, I had to use rest_{$this->post_type}_query

/* change amount of posts returned by REST API to 100 */
function rest_posts_per_page( $args, $request ) {
    $max = max( (int)$request->get_param( 'per_page' ), 100 );
    $args['posts_per_page'] = $max;
    return $args;
}
add_filter( 'rest_post_query', 'rest_posts_per_page', 10, 2 );
Fraser answered 26/6, 2018 at 6:1 Comment(0)
B
2

I hope this help, I'm using axios but is the same other

async multipleRequests() {
                let npage = 1;
                let url = `/sites/mysite.com/wp-json/wp/v2/posts?page=${npage}&per_page=10`;
                let { data } = await axios.get(url);
                let tempdata = data;  

                while (tempdata.length > 0) {
                    npage++;
                    let url = `/sites/mysyte.com/wp-json/wp/v2/media?page=${npage}&per_page=10`;
                    let { data } = await axios.get(url);                    
                    tempdata = data;
                }
            }
Bulbil answered 27/6, 2021 at 5:2 Comment(0)
F
1

Try this, this works fine (WP 5.8.1)

add_filter( 'rest_{YOU_CPT}_collection_params', function ( $params, WP_Post_Type $post_type ) {
    if ( '{YOU_CPT}' === $post_type->name && isset( $params['per_page'] ) ) {
        $params['per_page']['maximum'] = PHP_INT_MAX;
    }
    return $params;
}, 10, 2 );
Fetiparous answered 16/9, 2021 at 15:19 Comment(0)
H
0

If you are planning on doing this with other parameters, you can also add categories etc as well. EG:

https://www.website.com/wp-json/wp/v2/posts?categories=61&per_page=100
Hashum answered 15/6, 2018 at 12:15 Comment(0)
C
0

It's really possible to get more then 100 posts or terms (tags, categories).
You should use rest_{$this->post_type}_query hook (for posts) or rest_{$this->taxonomy}_query hook for terms.
But you have to know, that it's impossible to pass a per_page arg in your GET request with more then 100 value. WP API will throw an error immediately (the hook will not help): per_page must be between 1 (inclusive) and 100 (inclusive) (with 400 http status).
To get around this problem you should pass a per page value in another get argument. And after this to trace this value in your hook.
So the code is:

For posts

add_filter( 'rest_post_query', 's976_rest_post_per_page', 2, 10 );
function s976_rest_post_per_page( array $args, WP_REST_Request $request ) {
    $post_per_page = $request->get_param('s976_per_page') ? $request->get_param('s976_per_page') : 10;
    $args['posts_per_page'] = $post_per_page;
    return $args;
}

For terms

add_filter( 'rest_category_query', 's976_rest_cats_per_page', 2, 10 );
function s976_rest_cats_per_page( array $prepared_args, WP_REST_Request $request ){
    $cats_per_page = $request->get_param('s976_per_page') ? $request->get_param('s976_per_page') : 10;
    $prepared_args['number'] = $cats_per_page;
    return $prepared_args;
}

Of course, for this to work, you have to pass s976_per_page (with any value like 500, 99999) argument in GET request.

Castalia answered 26/1, 2019 at 20:29 Comment(0)
T
0


I have been using this 's976_per_page' bit of code successfully so many thanks,but It only returns the 'publish' tagged posts,..
How could I get this to grab ALL statuses, or, alternatively, only a set / subset of statuses
Many Thanks
JMB

Taxiplane answered 25/12, 2019 at 7:44 Comment(0)
R
0

According to documents, 100 is maximum to get. If you want more, use offsets and multiple requests. Example:

$i              = 0;
$check_for_more = true;

while ( $check_for_more ) {
    $offset  = $i * 100;
    $url     = network_site_url( "/wp-json/wp/v2/office?order=asc&orderby=title&per_page=100&offset={$offset}" );
    $offices = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );

    if ( $offices ) {
        if ( count( $offices ) < 100 ) {
            $check_for_more = false;
        }
        foreach ( $offices as $key => $office ) {
            // Do what you want
        }
    } else {
        $check_for_more = false;
    }
    $i ++;
}
Retinitis answered 9/3, 2021 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.