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.
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.
- You’ve updated WordPress core to at least 4.4 (and ideally always keep it up-to-date!).
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.
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.
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
- a custom plugin, ensuring that your custom meta boxes exist regardless of theme
Here’s the code:
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_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:
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
- 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.
I’d love to hear more ideas of how you might use custom meta boxes and the REST API. Leave a comment below.