Fetching Post Data using the WordPress JSON API Plugin

By Rob Gravelle

Fetching Post Data using the WordPress JSON API Plugin

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.


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:



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);


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.

Rob Gravelle

Rob Gravelle resides in Ottawa, Canada, and is the founder of Gravelle Web Design. Rob has built systems for Intelligence-related organizations such as Canada Border Services, CSIS as well as for numerous commercial businesses.

In his spare time, Rob has become an accomplished guitar player, and has released several CDs. His band, Ivory Knight, was rated as one Canada's top hard rock and metal groups by Brave Words magazine (issue #92) and reached the #1 spot in the National Heavy Metal charts on Reverb Nation.

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
Thanks for your registration, follow us on our social networks to keep up-to-date