Retrieving post meta with REST API using \register_meta()

WordPress Codex suggests two ways of adding post meta to the response. I'm trying to achieve this with register_meta() since it kinda seems to be the correct way to me.

PROBLEM:

meta field in the response remains empty when I use register_meta() although show_in_rest is set to true.

SOLUTION:

Thanks to Allan Fuller, who pointed out, that the $object_type parameter (the first one in register_meta() function should be post and not the post type. This is also mentioned in the comments section of the new code reference


Description before solution

Here how am I doing this:

Step 1: call from functions.php:

\add_action('init', [$this, 'init'], 10); 

Step 2: register custom post type in the init function:

\register_post_type( CompanyPostType::POST_TYPE_NAME, [ 'labels' => [ 'name' => __('Companies'), 'singular_name' => __('Company') ], 'public' => true, 'show_in_rest' => true, 'rest_base' => CompanyPostType::REST_BASE, 'has_archive' => false, 'rewrite' => false, 'supports' => [ 'custom-fields', 'revisions' ] ] ); 

Step 3 - profit: register meta for the custom post type in the init function

$meta = [ 'key' => CompanyPostType::META_NAME, 'description' => 'Name of the company', 'type' => 'string' ], \register_meta(CompanyPostType::POST_TYPE_NAME, $meta['key'], [ 'show_in_rest' => true, 'single' => true, 'type' => $meta['type'], 'description' => $meta['description'], ] ); 

The meta field is still remains empty in the response. If I however use the second way also suggested in the codex (register_rest_field()) in the same init hook:

\add_action( 'rest_api_init', function () { \register_rest_field( CompanyPostType::POST_TYPE_NAME, CompanyPostType::META_NAME, array( 'get_callback' => function($params ) { $meta = \get_post_meta( $params['id'], CompanyPostType::META_NAME, true); return (string) $meta; }, ) ); } ); 

then the field with its value appears in the response. What am I missing?

Since I'm using a custom post type, it may be worth looking at this part of code as well. As stated in the codex, when registering it I set ‘supports’ => [‘custom-fields’] so that custom fields appear in the rest response. The whole looks like this:

 return \register_post_type( self::POST_TYPE_NAME, [ 'labels' => [ 'name' => __('Companies'), 'singular_name' => __('Company') ], 'public' => true, 'show_in_rest' => true, 'rest_base' => self::REST_BASE, 'has_archive' => false, 'rewrite' => false, 'supports' => [ 'title', 'custom-fields', 'revisions' ] ] ); 

EDIT:

I tried, as suggested by Allan Fuller in his blog post, to put \register_meta() in rest_api_init hook, but it has no effect on meta in the response.

2

1 Answer

If you want to use register_meta to work, you have to explicitly hook it to rest_api_init
so for your example

add_action( 'rest_api_init', 'register_posts_meta_field' ); function register_posts_meta_field() { register_meta('post', $meta['key'], [ 'show_in_rest' => true, 'single' => true, 'type' => $meta['type'], 'description' => $meta['description'], ] ); } 

The above is untested but see working plugin version of code here

The object type needs to be 'post' to the custom post type name

see

first argument is object_type - valid object types are predefined by wordpress and CPT is a type of post

4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like