CMB2 & the WP REST API

Update:CMB2 has added support for the REST API. While this method is still valid, I encourage you to review my follow-up post as well as their documentation.

CMB2 opens a lot of doors with WordPress development, making it possible to store all sorts of meta, or extra, information about each post. Typically, meta information includes fields like Categories or Tags, but there’s really no limit to what sorts of meta information you can store.

Typically, creating and storing meta information is a tedious process, requiring you to set up functions to show the boxes, to store the boxes, to show any stored values in the boxes, and so on. Because WordPress doesn’t really have a comprehensive meta API, CMB2 opens the floodgates by allowing you to add meta fields with only a few lines of code.

Even better, those meta fields aren’t just limited to text. CMB2 offers a ton of great field types, from dropdowns and image galleries to color pickers and a full WYSIWYG editor. There are also some great open source additions, like this one I’ve used that offers a Google Maps object as a field, storing latitude and longitude values for you. Connect that to the Google Maps API and you’ve got yourself a stew, baby.

Preface

Before we get started, I would like to clarify that this tutorial makes a few assumptions:

You want to use the REST API, exposing aspects of your data as publicly-accessible, read-only JSON.

You’re somewhat familiar with the idea of CMB2.

You feel confident editing your theme’s functions.php, creating a separate file and using require_once, or writing a custom plugin. Here’s a previous article with more thoughts on data organization and how I typically deal with custom meta/custom post types.

If you have any questions about any of those concepts, leave a comment and I’ll be happy to discuss and share some resources that have helped me in the past.

Step One – Install The Necessary Plugins

You’ll need a few plugins to get both CMB2 and the WP REST API working. In addition to that, there are a number of other plugins that offer some great ‘enhancements’ to both. I recommend taking some time thinking about the type of data you’d like to collect and how you plan on using it.

WP REST API

The REST API is currently available as a feature plugin. WordPress version 4.4 brought the first half of the API into core, but the second half is slated to be merged in 4.7 update. You can follow the release notes to learn more about the future of the REST API, but it’s sufficient for now to include the plugin. Reminder: Creating a REST API means that it’s possible to publicly access some meta information about your posts.

CMB2

You do not have to install CMB2 as a plugin and there are in fact many reasons why you may not want to. If you’re interested in bundling it with your theme, check out their official documentation on their github page; it’s pretty comprehensive. However, until the day comes that it is removed from the plugin directory, we can just install it as a plugin and go from there. Either way will work for the basic idea of this tutorial.

Other Plugins

When using the REST API, be sure to do a little research before you turn to CMB2. For example, we might be unhappy with the way featured images show up in the REST API and think a custom meta box is the best option. If we stopped using the default Featured Image field, we’d be missing out on a lot other functionality that may affect our theme and our meta information.

It’s important to be aware of these other options in case the default post options can be optimized, as in the case of one of my favorite plugins to use, Better REST API Featured Images. Weigh the pros and cons of utilizing the WordPress default objects and optimizing them versus creating things from scratch or external frameworks.

That being said CMB2 is a great plugin that does extend the standard WordPress meta without too much work on your part.

Step Two – Create our custom fields

We’re going to focus on adding these custom fields to the WordPress standard post type, but more often than not, you may be using these for custom post types you’ve created, like Newsletters, Links, Events, etc.

Generating custom post types for dynamic data on your website is a topic that I’m diving into with more depth over at my Super Custom WP series. Don’t worry. If you’ve made a custom post type, you can add these meta boxes by changing one line of code. Pretty easy.

Let’s take a look at a cleaned up version of the default example from the CMB2 wiki. Remember, this chunk of code can go in one of three places:

functions.php in your theme

a separate file, such as inc/custom-meta-boxes.php that is then included into your functions.php via require_once()

Starting with line 5, we’re adding an action that will hook into our WordPress installation, specifically into a function that CMB2 has already created. Long story short, whenever the ‘Edit Post’ page is called, it looks for any related actions and, through these functions, knows to display our new ‘meta’ boxes.

The actual meat of the action starts on line 7 where we write out our function. Our function is really centered around one object: $cmb. Creating a meta box is a two step process, the ‘box’ itself followed by the ‘fields’ inside of it. You’ll see the box itself being created in line 11 and two fields added at lines 24 and 34.

By thinking about your custom meta needs hierarchically, you can divide fields up into separate boxes: one box named ‘Location’ may include fields like ‘address’ and ‘city’ whereas another box named ‘Contact’ may include ‘phone’ and ’email’. If you decide that multiple post types need those same fields, you can just edit the 'object_types' value in line 14 to include multiple post types.

It’s important to note that because we’ve used a $prefix variable when giving unique IDs to our fields, the names for our examples will end up being _prefix_email and _prefix_url. This will come in handy when we want to retrieve those values. Email and url are just two examples of custom field types. Spend some time browsing the aisles at the Field Types page on the CMB2 wiki for more types of inputs.

Step Three – Connect Custom Fields to REST API

Connecting your meta fields to the REST API is a two step process, requiring two functions that work in sync with each other. It’s important to know how these functions are different and what role each plays.

Function 1 – prefix_get_custom_meta()

When dealing with our standard PHP templates, we can access meta information using the standard get_post_meta() function (reference).

When meta information is stored, we have a key, or general name that we’ve chosen to associate the values with, and the value, which is unique to each post. We tell get_post_meta() what key we’re looking up (stored as ‘_prefix_email‘ and ‘_prefix_url‘ in our example) and it returns the value for that specific post.

To make things a little easier for our REST API, we’re going to create a wrapper function for get_post_meta() that the REST API can call on when it needs the values. Because this is a simple wrapper function, it only needs to occur once. I recommend pasting it underneath the rest of our code so it sits out of our way. Let’s look at it:

As you can tell, it’s pretty much just returning get_post_meta() with a few specifics in place. Just leave this somewhere at the bottom of your file and then our second function can call on it as needed.

Function 2 – prefix_register_custom_meta()

When you call the REST API, you receive a JSON object containing all of the details about your post, including title, content, permalink, etc. While our previous function exists to retrieve the values for us, we need to actually register those value with our REST API so it knows to display them. We’re going to make use of another action, this one coming from our REST API plugin rather than CMB2.

Let’s take a look at our function:

In line 2, we’re hooking into to the ‘rest_api_init’ action and telling it to run our function, prefix_register_custom_meta(). Inside our function, we’re basically calling register_rest_field() for each of our custom meta fields. That function does exactly what we think it does, adding a new field to our REST API that will display our new meta information. We’ll call that function for each custom meta field we want to add to our sites REST API.

Let’s take a closer look at the function from lines 4 to 12 and examine the three parameters we’re sending with the function:

Line 5 – Post type we’re working with. If your custom meta applies to more than one, use an array()

Line 6 – The ID of our custom meta field.

Lines 7-11 – Other arguments. What we’re mainly concerned with is line 8, the ‘get_callback’ parameter. As you can see here, we’ve included the name of our wrapper function from before.

Adding more fields? Repeat that register_rest_field() function and update the post type and custom meta field ID as needed.

And that’s it! Browse to your site’s REST API in the browser and take a look at that sweet JSON data.

Conclusion

Creating a REST API from your WordPress site may sound intimidating at first, but there’s a lot of the foundation already built for us. The possibilities that open up when you combine CMB2 and the REST API are pretty endless. Whether you want to display the data in a fun interactive way using some vanilla JS or a light Javascript library like Vue.js– or if you plan on accessing your site’s data through a new mobile app, the data is there for you.

I’d love to hear more ideas of how you might use custom meta boxes and the REST API. Leave a comment below.

Thanks for reading! I’m a big fan of CMB2 and use it pretty heavily. I remember seeing that on the repository a while back and I’m happy to hear that it’s in the works. It’s also a neat idea that you’re making an endpoint for the boxes.

Robert Tayloron April 22, 2017 at 11:12 am

THANK YOU BOTH!!! I was having a heck of a time discovering how to expose my CMB2 custom fields to the WP Rest API.

Though I ended up using the built-in CMB2 functionality, I’d like to thank you, Brian, for your original post. Without this post, I would never have found jtsternberg’s comment. (proof that I read it to the end!).

Thanks again, both.

Brian Coordson April 22, 2017 at 5:50 pm

Great to hear! I was thinking about deleting this post after CMB2 added REST API support, but I know that outdated articles can still help lead me to the right answer when I’m figuring something out too.