Mar 03, 2016 UPDATED: Updated all routes in this post so now should be compatible with WP API V2 beta 12. Feb 28, 2016 UPDATED: Just realised since v2 beta 4,
WP_Queryvars was moved back to
filterparam. I'll update all routes in this post ASAP.
In the post adding fields to the JSON response of the WP REST API, you’ve learned about how to manipulate the data from the WP REST API (WP-API). Another topic I got asked very often, is how to get posts by certain filters – mostly taxonomy and meta field. So today let’s talk about it.
Before we get started, if you’re looking for the workarounds for WP-API v1.x, Josh has written great tutorials for you. Here are the links of them:
In the following article, I’ll show you the quick answers and a more bigger picture beyond them. If you’re not interested in the later one, feel free to skip it.
The Quick Answers
*** Please note, starting from WP API v2 beta 4, you need to set
"show_in_rest" => true when registering a custom post type or taxonomy, to get it exposed to the JSON response. ***
So here are them. If you want to get posts by taxonomy with WP-API v2.0, you can use the endpoint/route like this: (
job-type is the taxonomy and
manager is the term you want to match)
Please note if you set the
false when registering the custom taxonomy, you’ll need to change the parameters to:
As to the default taxonomy – tag, the rule applies too:
But you need to be careful that with another default taxonomy – category, the parameter to use is
categor_name, so it’s like:
Get Posts By Meta Field Is Not Available By Default
When it comes to meta fields, you might already know that this is not working with WP-API by default (for security reason). When using the terms “by default”, you must be very happy to expect a workaround to hack it. And almost everything magic in WordPress is related to a hook – action or filter, so which is to the rescue in this case?
That’s it: the
rest_query_vars filter. Here’s how to use it:
With the hook, now you can use the route below to query posts by meta:
BTW, If you’re interested in getting custom post types worked with WP-API v2, please refer to the tips shared by @joneslloyd.
meta_query for complex meta key/value pairs?
If you want to query posts based on multiple meta key/value pairs, you must use
meta_query to do so. As the example above, we also need to add it to the valid query variables, like this:
And then you can use
meta_query with WP API v2. I know some people stuck in how to write arrays as GET/POST parameters, since
meta_query is an array composited by arrays, which looks pretty scary when thinking of converting it to URL parameters for
/posts route in WP API.
Luckily I found MailChimp have documented it in their API docs, be sure to check it out!
What’s The Bigger Picture?
When I was a junior developer (around 2007 – 2008), one of the things bothered me most is when the library or code I was working with wasn’t well documented. To be honest, back to those days I could barely get the job done even when the documentation was thoroughly. For example, I couldn’t build a web application with Zend framework on my own, which was very well documented then as I recall.
Years went by luckily I developed a few problem solving skills on programming, one of them is to refer to the source code when I can’t get clear answers from the documentation.
The series of building themes with AngularJS and WP REST API was focus on the AngularJS in the first 14 posts. But then I realized I need to spend more time with WP REST API since sometimes the questions from my readers can be solved easily if they understand better how the WP-API or WP_Query works.
It’s all about the query_vars
So let’s take a look at a simple but powerful function from the source code of WP-API:
get_allowed_query_vars function is from the
WP_REST_Posts_Controller class, which is in charge of what query variables (that we pass to the route like
tag) can be used to get posts with WP-API.
This function does the following jobs:
- Line 16: Get all valid query variables from
$wp->public_query_vars. We’ll introduce what exactly they are later.
- Line 18-33: If the user can
edit_posts, she/he can access more query variables with
$wp->private_query_vars, we’ll also talk about them later.
- Line 35: There are three more query variables added by WP-API:
- Line 47: At the end of this function, we can use the filter
rest_query_varsto modify all the query variables available. For example we can add or remove variables here. (We just learned the trick minutes ago.)
The public and private query variables lists
There’s a page on the WordPress codex for this but it seems not quite completed, so let’s look into the source code again, but in WordPress itself this time.
Tracing to the
wp-includes/class-wp.php, you’ll see the two variables we’re looking for:
$private_query_vars. Besides these variables when we register custom post types or taxonomies, if we set the
query_var to a string (can’t be empty string of course), it will be joined to the
Why posts_per_page Doesn’t Work (At Least In v2.0-beta3)
Now we know how many query variables are available. But after some tests I found a very interesting fact: the
posts_per_page parameter isn’t working.
I took another look at the source code of WP-API. From the same class (
get_items function helped me to figure that out:
At line 15 (from the gist above), you can see the WP-API actually gets
posts_per_page from another parameter called
per_page but not the
posts_per_page itself. I haven’t investigate every piece of code in WP-API so I can’t think of a good reason why it does so.
Improving The Security Of Meta Query When Working With WP-API v2.0
If you’ve kept an eye on WP-API for a while, you must notice that every time someone asks about the “meta query”, she/he will be reminded that “there might be some security risks” if exposing meta values to the WP-API.
I never store any confidential or sensitive data in post meta so I really hope things can be easier. But since WordPress and WP-API don’t work that way, let’s see what else we can do.
Limiting The Meta Keys Can Be Queried
No matter which filter you use to add the
meta_value to the
$valid_vars (you can use
rest_query_vars), you basically allow all meta fields can be queried. If it’s too risky to you, try to limit the
meta_key to only allowed fields with
I hope you enjoy this post and would love to spend more time to know WP-API v2.0 better. If you encounter any question when following the steps from this tutorial, just shoot me an email: yoren [at] 1fix.io, or ping me on Twitter (@1fixdotio), and comments are much welcome. Talk soon!