6

I added meta box City and Location to my post, but when I calling the endpoint (by WP Rest API) /wp-json/wp/v2/<post_type>/<post_id> it's not returning my meta data.

I tried to use register_meta like this, but still not working:

register_meta('my_post_type', 'city', [
    'type' => 'string',
    'description' => 'Cidade',
    'single' => true,
    'show_in_rest' => true
]);

What should I do to return it?

10

The first parameter passed to register_meta() is always post for posts, Pages (post type of page) and custom post types.

However, the REST API Handbook says that:

Prior WordPress 4.9.8, meta fields set to show_in_rest using register_meta are registered for all objects of a given type. If one custom post type shows a meta field, all custom post types will show that meta field. As of WordPress 4.9.8 it’s possible to use register_meta with the object_subtype argument that allows one to reduce the usage of the meta key to a particular post type.

So this should work:

register_meta('post', 'city', [
    'object_subtype' => 'my_post_type', // Limit to a post type.
    'type'           => 'string',
    'description'    => 'Cidade',
    'single'         => true,
    'show_in_rest'   => true,
]);

But then, the REST API Handbook also says:

Note that for meta fields registered on custom post types, the post type must have custom-fields support. Otherwise the meta fields will not appear in the REST API.

So make certain that your post type has support for custom-fields:

register_post_type(
    'my_post_type',
    array(
        'supports' => array( 'custom-fields', ... ), // custom-fields is required
        ...
    )
);

Alternate Solution

This one uses register_rest_field() and you can easily use my_post_type in the code. But this is of course a simplified example and you should check the handbook for more information:

add_action( 'rest_api_init', function () {
    register_rest_field( 'my_post_type', 'city', array(
        'get_callback' => function( $post_arr ) {
            return get_post_meta( $post_arr['id'], 'city', true );
        },
    ) );
} );

Also, the metadata will not be in meta, but instead in the top-level just as the meta property. Sample response body/string: (just part of the full response)

  • With register_meta(): ,"meta":{"city":"London"},

  • With register_rest_field(): ,"meta":[],"city":"London",

| improve this answer | |
  • It's still not returning the meta field – Lai32290 Mar 18 '19 at 11:23
  • Please check the updated answer. – Sally CJ Mar 18 '19 at 14:12
  • That's great! actually I'm using the Alternate Solution for now, but then I'm wondering if it's the correct way, because it's basically doing a new request to the database, as I know, is it going to impact the performance if I have a massive requests? – Lai32290 Mar 19 '19 at 10:13
  • Metadata requests (using the WordPress API/functions) are cached, and actually, even with the non Alternate Solution, WordPress also performs the same request, except it uses get_metadata() directly and not get_post_meta() which is a wrapper to get_metadata() for post meta. And the reason to why I added the alternate solution is in case your post type can't/don't have support for custom-fields. I hope these helps you, even if not much.. :) – Sally CJ Mar 19 '19 at 11:56
  • Thanks a lot! it really helped me – Lai32290 Mar 19 '19 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.