0

I have created a custom post type and I got it to show in the REST API. I have also registered a custom field using the following code :

function slug_get_post_meta_cb( $object, $field_name, $request ) {
    return get_post_meta( $object[ 'id' ], $field_name );
}

function slug_update_post_meta_cb( $value, $object, $field_name ) {
    return update_post_meta( $object[ 'id' ], $field_name, $value );
}

add_action( 'rest_api_init', function() {
 register_rest_field( 'custom_type',
    'myfield',
    array(
       'get_callback'    => 'slug_get_post_meta_cb',
       'update_callback' => 'slug_update_post_meta_cb',
       'schema'          => array(
           'type' => 'string',
           'context' => array( 'view', 'edit' )
       ),
    )
 );

I'm using jQuery to create an ajax POST request in order to create a new custom post with the following javascript code :

jQuery.ajax( {
                    url: requete.api,
                    method: 'POST',
                    beforeSend: function ( xhr ) {
                        xhr.setRequestHeader( 'X-WP-Nonce', questionnaireScript.nonce );
                    },
                    data:{
                        title : myData.title,
                        content: myData.content,
                        status: "publish",
                        myfield: "Stop flying"
                    }
                } ).done( function ( response ) {
                    console.log( response );
                } );

The posts are created all right, by without the custom field myfield . It does show up as part of the custom post object in the response to a GET request, but as an empty array. I also tried to set it as myfield : ["Stop flying"], and as meta : {myfield: "Stop flying"}, to no avail. I am aware of the other WP function to register a meta field (register_meta). However since the documentation reads that it cannot be applied to a custom post type only I chose to use register_rest_field instead. Any idea what I'm doing wrong ?

2 Answers 2

2

I haven't tested your code, but here the $object is an object and not array:

// Here, $object is a WP_Post object.
function slug_update_post_meta_cb( $value, $object, $field_name ) {
    return update_post_meta( $object->ID, $field_name, $value );
}

And you can actually use register_meta() with a custom post type:

register_meta( 'post', 'myfield', [
    'object_subtype' => 'custom_type', // Limit to a post type.
    'type'           => 'string',
    'description'    => 'My Field',
    'single'         => true,
    'show_in_rest'   => true,
] );

Check my answer here for more details.

8
  • I tried replacing all the php code I posted above by register_meta, but now I don't even see the custom field in the objects I get in the GET response. Do you know why ? Commented Jun 27, 2019 at 16:13
  • Also, I see that the argument "object_subtype isn't listed in the documentation : codex.wordpress.org/Function_Reference/register_meta Commented Jun 27, 2019 at 16:15
  • That's an outdated doc. See here for an updated one. Also, did you read everything here? Make sure your custom post type supports custom fields.
    – Sally CJ
    Commented Jun 27, 2019 at 16:20
  • 1
    But with your original code in the question, you could just try to use $object->ID instead of $object['id'] in the slug_update_post_meta_cb().
    – Sally CJ
    Commented Jun 27, 2019 at 16:23
  • 1
    I tried again with a full stomach, and a walk outside, with the fix you proposed to my original code, and it works ! Thank you very much, that was very helpful. Commented Jun 27, 2019 at 18:46
0

Try and JSON.stringify() your data as you pass it over, and send it over as that type:

// Data to pass over
obj_to_pass = {
  title : myData.title,
  content: myData.content,
  status: "publish",
  myfield: "Stop flying"
};
// Updated AJAX call
jQuery.ajax( {
  url: requete.api,
  method: 'POST',
  beforeSend: function ( xhr ) {
    xhr.setRequestHeader( 'X-WP-Nonce', questionnaireScript.nonce );
  },
  dataType : 'json',
  data: JSON.stringify(obj_to_pass)
} ).done( function ( response ) {
  console.log( response );
} );

I felt like I have had issues with it in the past. I don't have a good testing environment to test it in, so fingers crossed!

2
  • Thank you for the suggestion. It doens't work, unfortunately. There must be something else going wrong. Commented Jun 27, 2019 at 16:06
  • It turns out it had nothing to do with my JS code, but there was a mistake on the php side. Commented Jun 27, 2019 at 18:47

Your Answer

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

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