7

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?

1 Answer 1

14

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",

6
  • It's still not returning the meta field
    – Lai32290
    Mar 18, 2019 at 11:23
  • Please check the updated answer.
    – Sally CJ
    Mar 18, 2019 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, 2019 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, 2019 at 11:56
  • Thanks a lot! it really helped me
    – Lai32290
    Mar 19, 2019 at 11:58

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .