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.


