WP Rest API Tips

Cowboy riding a horse standing up.


Cowboy Jason Stanley performing a riding trick at the Round-Up, Pendleton, Oregon flickr photo by UW Digital Collections shared with no copyright restriction (Flickr Commons)

I’ve been doing quite a bit more with the WordPress Rest API lately. There’s plenty of documentation and tutorials out there but most of it still feels a bit scattered to me so I’m going to stick a few of the basics here and add a few things that have come up repeatedly that aren’t quite as basic. There’s an attempt here to move upwards in complexity with the examples but to keep them as clean as possible.

This will deal entirely with getting the data. I haven’t done much with using the API to write or modify data.

Get the Info

There are many ways to get data depending on your library of choice or if you’re using vanilla JS. I’ve played with fetch and Axios on the lighter side and jQuery, Vue, and Angular (v1) on the heavier/more involved side of things.

I’ll use jQuery in this version because it’s fairly popular but here’s a Vue example. The example below does a basic jQuery ajax call for the JSON associated with blog information.

See the Pen simple jquery get of WP JSON for the site by Tom (@twwoodward) on CodePen.

The URL Structure/Accessing the Blog Info

Using the codepen above as the example . . .

First, we’re fetching the JSON from the following URL. You can go there now and just take a look at it in wild if you’d like.
https://bionicteaching.com/wp-json/

I use a Chrome extension called JSON formatter to make the JSON all pretty (like the image below).

Navigating the JSON is pretty straightforward but it’s never a bad idea to over-explain. In these examples, I stored the JSON as a variable named data. You could name it anything but data is pretty standard.

  • get the site title – data.name
  • get the site description/tagline – data.description
  • get the site URL – data.url
  • get the third namespace – data.namespaces[2] – I don’t really know what you’d do with this but I did it as an example of navigating an array (square brackets) vs an object (curly brackets). Alos worth noting that array counting starts at 0 rather than 1. Asking for namespace[3] will get you an ‘undefined’ response.

See the Pen simple jquery get of WP JSON by Tom (@twwoodward) on CodePen.

Getting Posts

The vanilla post URL is https://bionicteaching.com/wp-json/wp/v2/posts/. That’ll get you all the basics- title, excerpt, content etc. What isn’t necessarily obvious is that https://bionicteaching.com/wp-json/wp/v2/posts?_embed now gives you access to the features images, tags, categories etc. That’s handy. I’ll be using the second version in this example so we can pull the featured image (if it exists).

See the Pen simple jquery get of WP JSON with _embedded by Tom (@twwoodward) on CodePen.

Some additional things worth knowing about the posts endpoint . . .

Those are the ones I’ve used most frequently and they’ll provide a decent pattern for the other parameters which are documented here.

Now that we’ve got some data from some URL we’ve constructed, let’s display the data. It’s going to work pretty much the same as the first example but we’re going to throw in an ‘each’ element to repeat the action for each post that is returned.

  $.each(data, function(index, item) {
              $('#posts').append('<h2 ' + backgroundImg(item) +'>'+item.title.rendered+'</h2>');//adds an h2 element with the title to the div with id posts
            }); //each 

That’s fairly in line with what we’ve done before with the exception of the backgroundImg() function. I do that just to simplify things a bit because the path to the background img url is a bit involved and I’d like to have a backup image if the post doesn’t have a featured image.

function backgroundImg (item) {
//first check if there is a featured image or else things will fail
      if(item._embedded['wp:featuredmedia']){
//then ge the url for the image size you want 
       var imgUrl = item._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url;
        return 'style="background-image:url('+imgUrl+');"';
      }
    else {
        return 'style="background-image:url(https://c1.staticflickr.com/5/4165/34235788350_ce2563a421_q.jpg);"';
      }
    }

Take note of the way we access the featured image url.
item._embedded[‘wp:featuredmedia’][0].media_details.sizes.thumbnail.source_url
That’s not necessarily intuitive. The colon would break things if you didn’t have the brackets and the quotes and then since it’s an array, you need to move to the first element with the [0]. I don’t know the logic behind throwing in a colon for this key name but it would have made life easier if they had done something else.

You can do lots of fun things with this stuff. Here’s another example that auto-loads additional posts via scroll trigger. Nothing too fancy, but it starts to get at some interesting possibilities.

Custom Fields

By default WP doesn’t expose your custom fields in the JSON. That could be good if you have secrets there . . . but I don’t. There’s a plugin to do it but you can also allow access on a field by field basis by adding the following to your functions.php file. This is straight from the WP handbook and is referencing a custom field called bp_avatar.

// The object type. For custom post types, this is 'post';
// for custom comment types, this is 'comment'. For user meta,
// this is 'user'.
$object_type = 'post';
$args1 = array( // Validate and sanitize the meta value.
    // Note: currently (4.7) one of 'string', 'boolean', 'integer',
    // 'number' must be used as 'type'. The default is 'string'.
    'type'         => 'string',
    // Shown in the schema for the meta key.
    'description'  => 'bp avatar',
    // Return a single value of the type.
    'single'       => true,
    // Show in the WP REST API response. Default: false.
    'show_in_rest' => true,

);
register_meta( $object_type, 'bp_avatar', $args1 );//this is the actual name of the field rather than the description above

One thought on “WP Rest API Tips

Comments are closed.