2

I used this semi-official plugin to enable API call.

But I can't find a way to exclude category. For example if I have mysite.com/wp-json/wp/v2/posts?filter[category__not_in]=10, it will ignores the filter and show all latest posts.

Is there a way to exclude category from the API call?

hrsetyono
  • 4,474
  • 13
  • 46
  • 80
  • Can't you upgrade to 4.4? The Rest API is part of the core now. – vard Dec 21 '15 at 16:29
  • @vard Oh I already upgraded to 4.4, but I think it still needs the plugin. – hrsetyono Dec 21 '15 at 17:25
  • Mmh it shouldn't, do you have any error when you deactivate it and try to use the rest api? (I'm not sure if by default it use the 2.0 or 1.0 version of the API, but it can be set through the config) – vard Dec 21 '15 at 17:26
  • I just tested and it doesn't work without plugin. But going to `mysite.com/wp-json/` gives json about my site name, description. I think 4.4 added filter that allow plugin to easily create json. – hrsetyono Dec 21 '15 at 17:35

2 Answers2

2

With the Rest API some filters are available only for logged in users:

In addition, the following are available when authenticated as a user with edit_posts:

[...]

category__not_in

This is taken from the Rest API 1.0 documentation.

What that mean is you need to logged in as an editor (user with edit_posts capability). For doing this in a clean way, I suggest create a minimal role for REST user with only the capabilities you need, something like this:

add_role(
    'rest_user',
    __( 'REST User' ),
    array(
        'read'         => true,
        'edit_posts'   => true,
        'delete_posts' => false
    )
);

Then do your query as authenticated user with the following:

$response = wp_remote_request('http://example.com/wp-json/wp/v2/posts?filter[category__not_in]=10', array(
    'method' => 'GET',
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode('login:password')
    )
));

Thanks to this article you shared, it seems you need to declare the filter name as query var, so in this case:

add_filter('query_vars', function($query_vars) {
    $query_vars[] = 'category__not_in';
    return $query_vars;
});

Which make sense because Wordpress is droping any GET parameter that isn't declare, though I don't understand why all the filters are not declared as query vars inside the WP Core...

vard
  • 4,057
  • 2
  • 26
  • 46
  • I already logged in as admin and when I go directly to the URL, it still shows all unfiltered latest post. Maybe it's bug with v2? – hrsetyono Dec 21 '15 at 17:28
  • Maybe - the text I quoted is from the v1 doc - I don't see any reference to this filter values in the v2 doc. I suggest to give it a try with the 1.0 version and see if it help. – vard Dec 21 '15 at 17:30
  • I put a bug report in their repo and got [the same answer](https://github.com/WP-API/WP-API/issues/1884#issuecomment-166351516). Let's wait for their next reply. – hrsetyono Dec 21 '15 at 17:48
  • Could you try with an other auth filter like `offset` and see if it works? It would help to know if it's a auth problem or something specific to `category__not_in` filter. – vard Dec 21 '15 at 17:50
  • All variable that is under "must be authenticated" doesn't seem to work. I used the same browser to directly access the json URL, so I should have been authenticated right? – hrsetyono Dec 21 '15 at 17:55
  • 1
    I just got the answer from [this post](https://1fix.io/blog/2015/02/28/wordpress-rest-api-media/). I put `$query_vars[] = 'category__not_in';` and it works. Thanks a lot for your time :). You can edit your answer and I will accept it. – hrsetyono Dec 21 '15 at 17:57
  • Ah very good to know. I updated my answer to add info about this. Though I feel like this is a bit redundant, Wordpress should add those query vars himself... – vard Dec 22 '15 at 08:42
-2

For WP API V2 use a minus sign, for example:

http://yourwpwebsite/wp-json/wp/v2/posts/&filter[cat]=1,2,-3

will retrieve all posts in categories with id= 1 and id = 2 but excluding any posts in category with id= 3

USER249
  • 1,080
  • 7
  • 14