Headless WordPress Category Rest API

May 4th 2020

We recently moved from a monolithic WordPress CMS website to a JAMStack setup built on Nuxt.js, CI/CD hosted on Netlify and supported by Strapi.io. Yet, we haven’t made the full transition away from WordPress as we’re still managing our blog content through the platform. Instead of running WordPress in a traditional monolithic CMS, we moved our WordPress instance to a headless CMS setup using the WordPress Rest API.

In our headless WordPress setup we needed to pull all of our categories from the API which comes out of the box with the WordPress Rest API, but we needed to be able to add an image field that we could display on our front-end category page. Since we were already using an advanced custom field to create an image field for each of our categories we need to register rest field in our headless WordPress installation to get the image for the category we are requesting.

Advanced Custom Field Taxonomy

We could add a custom field to our category taxonomy using vanilla WordPress via add_term_meta and retrieve the field using get_term_meta. But since we’re uploading media and saving an image it would add some extra work to create a custom field, but we’re going to use the popular Advanced Custom Field plugin to quickly add a field to our category taxonomy.

You can install the plugin by uploading and installing the plugin to your WordPress site as you would any other plugin. Once installed you can navigate to the “Custom Fields” link in the left hand sidebar.

Once on the page we can create a new “Field Group” and we can call it “Category Field Group”. We will be adding a new field called “Category Image” and make sure the field name populates with category_image. The field type is going to be “Image” and for the return format we can select “Image URL”. Once we have that we can scroll down to “Rules” and make sure that Show this field group if and that “Taxonomy” is selected and “is equal to” is selected and in the last drop down “Category” is selected.

We can save the field group and then we can navigate to our “Categories” taxonomy under the Posts link in our left hand sidebar. We can drill down into a Category and you should be able to see the new field we created “Category Image” and we can populate our Categories with images as needed.

WordPress Register Rest API Category

Now that we have our images for our categories populated we will need to use the WordPress Rest API to retrieve the categories for our posts. The WordPress Rest API allows us to fetch our categories through the Rest API out of the box: https://developer.wordpress.org/rest-api/reference/categories/ via a call to our WordPress instance such as: curl https://example.com/wp-json/wp/v2/categories. However, we will not see the category_image field that we created with the Advanced Custom Fields plugin. In order to return this field with the REST Endpoint request we will need to hook into the WordPress register_rest_field which will register a new field on an existing WordPress object type. We can add hook into this action in our functions.php file located in our theme or in a custom plugin. For ease of use, we will use our functions.php file to hook into the register_rest_field. Let’s open up our functions.php file in our theme and take a look at what the register_rest_field would look like:

<?php
add_action('rest_api_init', function () {
  /*Add category image*/
  register_rest_field(
    'category',
    'category_image',
    array(
      'get_callback' => function ($object, $field_name, $request) {
        return get_field('category_image', $object['taxonomy'] . '_' . $object['id']);
      },
      'schema' => array(
        'description' => 'Category Image Field',
        'type' => 'string',
        'context' => array('view')
      )
    )
  );
}, 99);

In our functions.php file we are using add_action to the rest_api_init hook which accepts a callback function. Inside the init hook we are using the function register_rest_field and we’re registering the field to our category term object and we’re calling our returned field in the REST request category_image. The final argument for the register_rest_field is an array in which we need to define a get_callback property in our associative array which is a function definition. Let’s break down this function:

function ($object, $field_name, $request) {
  return get_field('category_image', $object['taxonomy'] . '_' . $object['id']);
}

In this function we are using the advanced custom field method get_field to get the value of the category field. This function takes the name of the field and then we have to pass in the id of the object that is associated with the field. Most of the time if you are getting a related field of a post or a page all you need to pass in is the post’s id. However, for a WordPress Term Object object the format has to be [taxonomy type]_[term id] so in our case it should look like category_21 as an example to get the category_image field for category with id of 21.

Testing the WordPress Rest Category Endpoint

We should now be able to call our endpoint to test if our field value is returned. You can use Postman or the curl method to send a GET request to our categories endpoint: https://example.com/wp-json/wp/v2/categories and you should get a JSON response object:

[
    {
        "id": 121,
        "count": 6,
        "description": "Nuxt is an open source framework built on Vue.js which makes web development simple and powerful.",
        "link": "https://example.com/category/nuxt/",
        "name": "Nuxt",
        "slug": "nuxt",
        "taxonomy": "category",
        "parent": 0,
        "meta": [],
        "category_image": "https://example.com/wp-content/uploads/2020/05/nuxt-js-hash-interactive.jpg",
        "_links": {
            "self": [
                {
                    "href": "https://example.com/wp-json/wp/v2/categories/121"
                }
            ],
            "collection": [
                {
                    "href": "https://example.com/wp-json/wp/v2/categories"
                }
            ],
            "about": [
                {
                    "href": "https://example.com/wp-json/wp/v2/taxonomies/category"
                }
            ],
            "wp:post_type": [
                {
                    "href": "https://example.com/wp-json/wp/v2/posts?categories=121"
                }
            ],
            "curies": [
                {
                    "name": "wp",
                    "href": "https://api.w.org/{rel}",
                    "templated": true
                }
            ]
        }
    },
]

You can see that we indeed have a field of category_image which is what we defined in our register_rest_field function!

Conclusion

We successfully used the WordPress Rest API to add an image field for our categories to enhance our Headless WordPress instance. First, we had to use the plugin Advanced Custom Fields to configure an image field for our Category Taxonomy type. Then we were able to hook into the register_rest_field in our functions.php file, get the result of the image field and return it in our JSON response. Hopefully, this enhances your ability to use WordPress in a Headless CMS fashion and you can repeat this process with many other fields and field types! Until next time, stay curious, stay creative.