How do you get posts by meta_query using the JSON API plugin?

There are two parts to the solution here.

  1. You need to use a JSON API custom controller
  2. In your custom controller, you’ll need to decide how to pass the meta_query data structure

Depending on how robust you need this to be, you could use a variety of approaches. Here is the maximalist approach, that will allow any kind of meta_query, encoding the structure as a JSON string.

<?php

// 1. The class name must match the filename (i.e., "foo.php" for JSON_API_Foo_Controller)
// 2. Save this in your themes folder
// 3. Activate your controller under Settings > JSON API

class JSON_API_Example_Controller {

  public function get_posts_by_meta_query() {
    global $json_api;

    if (empty($_GET['meta_query'])) {
      return array(
        'error' => "Specify a 'meta_query' param."
      );
    }

    $query = array(
      'ignore_sticky_posts' => true,
      'numberposts' => -1,
      'post_type' => 'event',
      'meta_query' => json_decode($_GET['meta_query'], true)
    );
    return array(
      'posts' => $json_api->introspector->get_posts($query)
    );
  }
}

?>

So if you want to pass this meta_query as URL-encoded JSON:

$args = array(
  'numberposts' => -1,
  'post_type' => 'event',
  'meta_query' => array(
    'relation' => 'AND',
    array(
      'key' => 'place',
      'value' => 'Melbourne'
    ),
    array(
      'key' => 'dayoweek',
      'value' => 'saturday'
    )
  )
);

Encode it like so, in JavaScript:

var meta_query = encodeURIComponent(JSON.stringify({
  relation: 'AND',
  0: {
    key: 'place',
    value:'Melbourne'
  },
  1: {
    key: 'dayoweek',
    value: 'saturday'
  }
}));

Here’s how that would look as a URL query param (a bit unwieldy):
/?json=example/get_posts_by_meta_query&meta_query=%7B%220%22%3A%7B%22key%22%3A%22place%22%2C%22value%22%3A%22Melbourne%22%7D%2C%221%22%3A%7B%22key%22%3A%22dayoweek%22%2C%22value%22%3A%22saturday%22%7D%2C%22relation%22%3A%22AND%22%7D

Leave a Comment