How to correctly create Custom Post Type with custom fields through WP REST API V2

How do I correctly create a custom post type record through the wp rest api v2 with custom fields? Unable to create custom fields or update them.

I have installed the superlist and superlist-child theme in a self hosted wordpress installation.

Read More

This theme uses Custom Taxonomies for categories, locations, Custom Post Types called businesses and custom fields in post meta for the Custom Post Type

I am trying to import data to site using rest api v2 and have successfully created the custom categories and locations.
I used the REST API Enabler plugin to register the custom endpoints and the custom fields.

Using the businesses endpoint http://mysite/wp-json/wp/v2/businesses I can upload a new business through the api but the record created ignores all the meta keys

eg Given the following body

      body = {
        title: company_name,
        listing_address: [address], 
        listing_map_location_latitude: [c.lat],
        listing_map_location_longitude: [c.lon],
        content: c.description,
        email: c.email,
        facebook: [c.facebook],
        image_url: c.image_url,
        locations: [c.city.server_id],
        listing_categories: c.categories.pluck(:server_id),
        listing_street_view: ["on"]
        status:"publish"
      }
      request = HTTParty.post(POSTS_END_POINT, body: body, headers: headers)

Correctly attaches the business to the correct location and custom categories (listing_categories) previously created through the REST api however none of the custom fields (wp_postmeta table) are populated e.g. listing_locations lon and lat fields and listing_address

I can query the record uploaded through the rest api and I get a response like this

$ rake upload:test
Result: {"id"=>1749, "date"=>"2016-02-20T05:06:01", "date_gmt"=>nil, "guid"=>{"rendered"=>"http://highstreetbeacons.com/?post_type=business&p=1749"}, "modified"=>"2016-02-20T05:06:01", "modified_gmt"=>nil, "slug"=>"", "type"=>"business", "link"=>"http://highstreetbeacons.com/?post_type=business&p=1749", "title"=>{"rendered"=>"Birmingham Museum and Art Gallery, Chamberlain Square, Birmingham, B3 3DH"}, "content"=>{"rendered"=>"<p>A description</p>n"}, "author"=>1, "featured_media"=>0, "comment_status"=>"open", "ping_status"=>"closed", "listing_categories"=>[3779, 4095, 4061], "locations"=>[330], "_links"=>{"self"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/businesses/1749"}], "collection"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/businesses"}], "about"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/types/business"}], "author"=>[{"embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/users/1"}], "replies"=>[{"embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/comments?post=1749"}], "https://api.w.org/attachment"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/media?parent=1749"}], "https://api.w.org/term"=>[{"taxonomy"=>"listing_categories", "embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/listing_categories?post=1749"}, {"taxonomy"=>"locations", "embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/locations?post=1749"}]}}

This totally ignores the meta keys.
If in the admin area I manually hit the update button for the generated business I can then re-query through the api and get all the correct fields returned but an POST request to update (Surely should be a PUT) the record still won’t set any of the custom fields

e.g.

rake upload:test
Result: {"id"=>1745, "date"=>"2016-02-20T04:53:17", "date_gmt"=>nil, "guid"=>{"rendered"=>"http://highstreetbeacons.com/?post_type=business&p=1745"}, "modified"=>"2016-02-20T04:53:17", "modified_gmt"=>"2016-02-20T04:53:17", "slug"=>"", "type"=>"business", "link"=>"http://highstreetbeacons.com/?post_type=business&p=1745", "title"=>{"rendered"=>"Birmingham Museum and Art Gallery, Chamberlain Square, Birmingham, B3 3DH"}, "content"=>{"rendered"=>"<p>A description</p>n"}, "author"=>1, "featured_media"=>0, "comment_status"=>"open", "ping_status"=>"closed", "listing_categories"=>[3779, 4095, 4061], "locations"=>[330], "listing_featured_image"=>[""], "listing_banner"=>["banner_featured_image"], "listing_opening_hours"=>["a:7:{i:0;a:4:{s:11:"listing_day";s:6:"MONDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}i:1;a:4:{s:11:"listing_day";s:7:"TUESDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}i:2;a:4:{s:11:"listing_day";s:9:"WEDNESDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}i:3;a:4:{s:11:"listing_day";s:8:"THURSDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}i:4;a:4:{s:11:"listing_day";s:6:"FRIDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}i:5;a:4:{s:11:"listing_day";s:8:"SATURDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}i:6;a:4:{s:11:"listing_day";s:6:"SUNDAY";s:17:"listing_time_from";s:0:"";s:15:"listing_time_to";s:0:"";s:14:"listing_custom";s:0:"";}}"], "listing_map_location"=>["a:2:{s:8:"latitude";s:0:"";s:9:"longitude";s:0:"";}"], "listing_street_view_location_latitude"=>["37.812405"], "listing_street_view_location_longitude"=>["-122.47607800000003"], "listing_street_view_location_heading"=>["-18"], "listing_street_view_location"=>["a:5:{s:8:"latitude";s:9:"37.812405";s:9:"longitude";s:19:"-122.47607800000003";s:4:"zoom";s:1:"1";s:7:"heading";s:3:"-18";s:5:"pitch";s:2:"25";}"], "listing_locations"=>["a:1:{i:0;s:10:"birmingham";}"], "listing_listing_category"=>["a:3:{i:0;s:7:"museums";i:1;s:10:"coffee-tea";i:2;s:13:"art-galleries";}"], "_links"=>{"self"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/businesses/1745"}], "collection"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/businesses"}], "about"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/types/business"}], "author"=>[{"embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/users/1"}], "replies"=>[{"embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/comments?post=1745"}], "https://api.w.org/attachment"=>[{"href"=>"http://highstreetbeacons.com/wp-json/wp/v2/media?parent=1745"}], "https://api.w.org/term"=>[{"taxonomy"=>"listing_categories", "embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/listing_categories?post=1745"}, {"taxonomy"=>"locations", "embeddable"=>true, "href"=>"http://highstreetbeacons.com/wp-json/wp/v2/locations?post=1745"}]}}

I have just created a plugin to register the custom fields rather than relying on REST API Enabler plugin with just one field to see if I can get that to work

<?php
/**
 * Plugin Name: Jamesc Register API Fields
 * Plugin URI: http://danielpataki.com
 * Description: This plugin exposes business meta data mfields to REST API.
 * Version: 1.0.0
 * Author: Smiler
 */


/**
 * Use arbitrary functions to add a field
 */
add_action( 'rest_api_init', 'register_something_random' );
function slug_register_something_random() {
    register_rest_field( 'business',
        'listing_address',
        array(
            'get_callback'    => 'get_meta_field',
            'update_callback' => 'update_meta_field',
            'schema'          => null,
        )
    );
}

/**
 * Handler for getting custom field data.
 *
 * @since 0.1.0
 *
 * @param array $object The object from the response
 * @param string $field_name Name of field
 * @param WP_REST_Request $request Current request
 *
 * @return mixed
 */
function get_meta_field( $object, $field_name, $request ) {
    return get_post_meta( $object[ 'id' ], $field_name );
}

/**
 * Handler for updating custom field data.
 *
 * @since 0.1.0
 *
 * @param mixed $value The value of the field
 * @param object $object The object from the response
 * @param string $field_name Name of field
 *
 * @return bool|int
 */
function update_meta_field( $value, $object, $field_name ) {
    if ( ! $value || ! is_string( $value ) ) {
        return;
    }

    return update_post_meta( $object->ID, $field_name, strip_tags( $value ) );

}

But this has no effect.

I am now totally stuck having tried everything I can think of.

Related posts

1 comment

  1. There was a glaringly obvious problem with my wordpress plugin where the add action function name did not match the actual function name
    register_something_random and slug_register_something_random()

    add_action( 'rest_api_init', 'register_something_random' );
    function slug_register_something_random() {
    

    Should be

    add_action( 'rest_api_init', 'register_something_random' );
    function register_something_random() {
    

    Made this change and all is now ok

Comments are closed.