How do you add custom fields defined in posts to the rest API responses in wordpress

Viewed 26672

I want to do this without using any sort of plugin since these are both core wordpress features (custom fields and the REST API). Here is the documentation for custom fields for reference:

https://codex.wordpress.org/Using_Custom_Fields

Here is a screenshot from my wordpress installation:

wordpress custom fields

Here is what the API response for a post looks like currently:

{
    "_links": {
        "about": [
            {
                "href": "http://example.com/wp-json/wp/v2/types/post"
            }
        ],
        "author": [
            {
                "embeddable": true,
                "href": "http://example.com/wp-json/wp/v2/users/1"
            }
        ],
        "collection": [
            {
                "href": "http://example.com/wp-json/wp/v2/posts"
            }
        ],
        "curies": [
            {
                "href": "https://api.w.org/{rel}",
                "name": "wp",
                "templated": true
            }
        ],
        "replies": [
            {
                "embeddable": true,
                "href": "http://example.com/wp-json/wp/v2/comments?post=21"
            }
        ],
        "self": [
            {
                "href": "http://example.com/wp-json/wp/v2/posts/21"
            }
        ],
        "version-history": [
            {
                "href": "http://example.com/wp-json/wp/v2/posts/21/revisions"
            }
        ],
        "wp:attachment": [
            {
                "href": "http://example.com/wp-json/wp/v2/media?parent=21"
            }
        ],
        "wp:featuredmedia": [
            {
                "embeddable": true,
                "href": "http://example.com/wp-json/wp/v2/media/23"
            }
        ],
        "wp:term": [
            {
                "embeddable": true,
                "href": "http://example.com/wp-json/wp/v2/categories?post=21",
                "taxonomy": "category"
            },
            {
                "embeddable": true,
                "href": "http://example.com/wp-json/wp/v2/tags?post=21",
                "taxonomy": "post_tag"
            }
        ]
    },
    "author": 1,
    "categories": [
        5,
        4
    ],
    "comment_status": "open",
    "content": {
        "protected": false,
        "rendered": ""
    },
    "date": "2017-05-14T15:25:33",
    "date_gmt": "2017-05-14T15:25:33",
    "excerpt": {
        "protected": false,
        "rendered": ""
    },
    "featured_media": 23,
    "format": "standard",
    "guid": {
        "rendered": "http://example.com/?p=21"
    },
    "id": 21,
    "link": "http://example.com/2017/05/14/post/",
    "meta": [],
    "modified": "2017-05-15T18:17:34",
    "modified_gmt": "2017-05-15T18:17:34",
    "ping_status": "open",
    "slug": "",
    "sticky": false,
    "tags": [],
    "template": "",
    "title": {
        "rendered": ""
    },
    "type": "post"
}

In case it could be relevant, here are my active plugins:

list of active wordpress plugins: Enable Media Replace, S3 Uploads

6 Answers

Suppose we want to add 'sku' and 'price' meta to the 'product' postType and the rest_api url is :

site_addresses.com/wp-json/wp/v2/product

Put this code in the functions.php

function af_create_custom_meta_in_REST()
{
    $post_types = ["product"]; //post types that will include custom fields
    foreach ($post_types as $post_type) {
        register_rest_field(
            $post_type,
            'custom_fields',
            [
                'get_callback'    => 'expose_custom_fields',
                'schema'          => null,
            ]
        );
    }
}
function expose_custom_fields($object)
{
    $fields = ["_sku", "_price"]; //custom fields name
    $post_ID = $object['id'];
    $return_value = [];
    foreach ($fields as $field) {
        $field = strval($field);
        $meta = get_post_meta($post_ID, $field);
        if (count($meta) > 1)
            $return_value[$field] = $meta;
        else if ($meta[0])
            $return_value[$field] = $meta[0];
        else
            $return_value[$field] = ""; //if you set this to null result will be 'null'
    }
    if ($return_value)
        return $return_value;
    return []; //if you set this to null result will be 'null'
}
add_action('rest_api_init', 'af_create_custom_meta_in_REST');

you can change $post_types or $fields to anything you want

Result image : image of rest_api reslut

Just add it in your CMS and then it should be available inside your WP REST API.

Related