WordPress JSON API Plugin utilizes RESTful style requests to fetch data from your WordPress database and make content available as a JSON feed. In the Provide a JSON Feed from your WordPress Site using the JSON API Plugin article we learned how to install the plugin and call its core info() and get_recent_posts() methods using Implicit or Explicit style. In today’s follow-up, we’ll cover a few other core methods for fetching post data as well as how to customize the output.
get_posts()
The get_posts() function is the bread and butter of the JSON API core methods. It fetches posts according to WordPress’s WP_Query parameters as well as three of its own own optional arguments. By default the ignore_sticky_posts parameter is set to 1, but can be overridden.
The three optional arguments are the same as for other functions such as get_recent_posts() and include:
- count: determines how many posts per page are returned (default value is 10)
- page: return a specific page number from the results
- post_type: used to retrieve custom post types
When used sans WordPress parameters, it acts in much the same way as get_recent_posts():
// "http://www.mywordpresssite.net/?json=get_posts&post_type=food" output: { "status": "ok", "count": 10, "count_total": 850, "pages": 87, "posts": [ { ... }, { ... }, ... ] }
To construct a more specific query, you an include some of the native WordPress WP_Query parameters. The following RESTful API call includes the year, orderby, and order WP_Query parameters:
http://mywordpresssite.net/?json=get_posts&post_type=rants&year=2012&orderby=title&order=asc
get_post()
Whereas get_posts() returns content based on flexible criteria, get_post() returns a single post object by ID or slug and only accepts the optional post_type argument.
// "http://www.mywordpresssite.net/?json=get_post&post_type=food&id=7479" output: { "status": "ok", "post": { ... } }
Customizing the Output Fields
The standard response contains a lot of information; maybe too much. On the other hand, perhaps you’d like to massage the data a bit and/or remove some sensitive or extraneous information. For that, the JSON-API plugin exposes a WordPress hook named json_api_encode that can be used to add, remove, or modify data to each fetched post.
But before we get into that, here is an example get_post() response formatted for readability using the “dev=1” parameter:
{ "status": "ok", "count": 1, "count_total": 1, "pages": 1, "posts": [ { "id": 1, "type": "post", "slug": "hello-world", "url": "http://localhost/wordpress/?p=1", "title": "Hello world!", "title_plain": "Hello world!", "content": "<p>Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!</p>n", "excerpt": "Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!n", "date": "2009-11-11 12:50:19", "modified": "2009-11-11 12:50:19", "categories": [], "tags": [], "author": { "id": 1, "slug": "admin", "name": "admin", "first_name": "", "last_name": "", "nickname": "", "url": "", "description": "" }, "comments": [ { "id": 1, "name": "Mr WordPress", "url": "http://wordpress.org/", "date": "2009-11-11 12:50:19", "content": "<p>Hi, this is a comment.<br />To delete a comment, just log in and view the post's comments. There you will have the option to edit or delete them.</p>n", "parent": 0 } ], "comment_count": 1, "comment_status": "open" } ] }
The json_api_encode hook is called just before the output is encoded into JSON format. The main data elements are contained within an associative array (i.e. $response[‘posts’]) while their elements are structured as PHP objects (i.e. $post->type). Single posts are stored in the $response[‘post’] element whereas multiple posts are stored in $response[‘post’], both of which are mutually exclusive. In the case of the latter, a foreach loop may be employed to iterate over each post object:
add_filter('json_api_encode', 'json_encode_acme_feed'); function json_encode_acme_feed($response) { if (isset($response['posts'])) { //multiple foreach ($response['posts'] as $post) { add_acme_feed_data($post); // Add data to each post } } else if (isset($response['post'])) { //single add_acme_feed_data($response['post']); // Add data to one post } return $response; }
To avoid duplication, we can place our code within a function. Note that the $post is passed in by reference so that changes to it carry over beyond the life of the function.
function add_acme_feed_data(&$post) { //remove unwanted fields if (isset($post->url)) { unset($post->url); } if (isset($post->author)) { unset($post->author); } if (isset($post->tags)) { unset($post->tags); } if (isset($post->content)) { unset($post->content); } if (isset($post->attachments)) { unset($post->attachments); } if (isset($post->excerpt)) { unset($post->excerpt); } if (isset($post->comments)) { unset($post->comments); } if (isset($post->comment_count)) { unset($post->comment_count); } if (isset($post->comment_status)) { unset($post->comment_status); } //replace source custom field if (isset($post->custom_fields->source)) { $post->custom_fields->source = fetch_main_source($post->id); } //add field $post->custom_fields->extra = getExtraInfo($post->id); }
Conclusion
In the next instalment we’ll learn how to go a step further on build our own controller. For those of you who are leery of working with a plugin that has not been updated for a while, we’ll be looking at some new contenders that provide similar functionality, once we’re done with the JSON API Plugin.