Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include META fields in Wordpress API Post?

I am using Wordpress version 5.2.1 which means I am not using a plugin for the WP API. I have working code which creates a new post (using a custom post type) on my WP site, all good there. The problem is that i've created custom fields using ACF, but they're not appearing in the newly created post. The following is an example of what I am sending to WP via: /wp-json/wp/v2/experience.

Note: experience is my custom post type.

{'title': 'test', 'content': 'testing from python', 'status': 'draft', 'author': 1, 'meta': {'location': 'NYC', 'date': 'never', 'event_url': 'http://google.com'}, 'featured_media': 1221}

This creates a post, but the fields inside of meta are completely ignored. My goal is to have the fields I specify in meta be included in my newly created post .

I have tried the solutions listed at the following URLs and nothing has worked.

https://gist.github.com/rileypaulsen/9b4505cdd0ac88d5ef51

Wordpress Rest API - Custom Fields

https://jeffreyeverhart.com/2017/06/14/adding-custom-fields-wordpress-json-api/

What am I missing?

like image 643
Peter Foti Avatar asked Jun 05 '19 12:06

Peter Foti


People also ask

What is post meta in WordPress?

Post meta data is information about a post, such as the date and time the post was published and the post author. The default meta data displayed with each post depends on which WordPress theme the site is using but usually includes some combination of the date, author, and post categories or tags.

How do I get meta key value in WordPress?

“get meta value by meta key in wordpress” Code Answer's php $key_1_value = get_post_meta( get_the_ID(), 'key_1', true ); ?>


2 Answers

First of all, you need to set the 'show_in_rest' property to true and 'supports' property should include 'custom-fields' when you are registering a new post type. You need to support 'custom-fields' if you want to include the meta fields.

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. https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/

function cptui_register_my_cpts() {

    /**
     * Post Type: Experiences.
     */

    $labels = array(
        "name" => __( "Experiences", "twentynineteen" ),
        "singular_name" => __( "Experience", "twentynineteen" ),
    );

    $args = array(
        "label" => __( "Experiences", "twentynineteen" ),
        "labels" => $labels,
        "description" => "",
        "public" => true,
        "publicly_queryable" => true,
        "show_ui" => true,
        "delete_with_user" => false,
        "show_in_rest" => true,
        "rest_base" => "",
        "rest_controller_class" => "WP_REST_Posts_Controller",
        "has_archive" => false,
        "show_in_menu" => true,
        "show_in_nav_menus" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => false,
        "rewrite" => array( "slug" => "experience", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "editor", "thumbnail", "custom-fields" ),
    );

    register_post_type( "experience", $args );
}

add_action( 'init', 'cptui_register_my_cpts' );

Now, you need to register the meta fields using the register_meta().

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

    register_meta( 'post', 'location', array(
        'type' => 'string',
        'description' => 'event location',
        'single' => true,
        'show_in_rest' => true
    ));

    register_meta( 'post', 'date', array(
        'type' => 'string',
        'description' => 'event location',
        'single' => true,
        'show_in_rest' => true
    ));

    register_meta( 'post', 'event_url', array(
        'type' => 'string',
        'description' => 'event location',
        'single' => true,
        'show_in_rest' => true
    ));

}

Note: The meta fields must be unique. Prefix your fields in ACF to make it unique.

JSON doesn't use single quotes to wrap a string. It uses double quotes. You are sending invalid JSON.

enter image description here

Now, if you want to create a experince post type. Use a JSON linter to validate your json. https://jsonlint.com/

Make a POST request to http://paathsala-plugin.test/wp-json/wp/v2/experience, with the fields

{
    "title": "test",
    "content": "testingfrompython",
    "status": "draft",
    "author": 1,
    "meta": {
        "location": "NYC",
        "date": "never",
        "event_url": "http: //google.com"
    },
    "featured_media": 1221
}

enter image description here

WordPress doesn't allow you create resource directly. You need to authenticate your REST request. I am using the Basic Auth for authenticating WordPress REST API. You need to install a plugin. Grab it from here: https://github.com/WP-API/Basic-Auth

I have tested the following python code.

import base64
import json
import requests;

# Data to be send
data = {
    "title": "test",
    "content": "testingfrompython",
    "status": "draft",
    "author": 1,
    "meta": {
        "location": "NYC",
        "date": "never",
        "event_url": "http: //google.com"
    },
    "featured_media": 1221
}

# I am using basic auth plugin to for WP API authenticaiton
username = 'admin'
password = 'blood9807'

# Encode the username and password using base64
creds = base64.b64encode(username + ':' + password)

# Create headers to be send
headers = {
    'Authorization': 'Basic ' + creds,
    'Content-type': 'application/json', 
    'Accept': 'text/plain'
}

# Convert the python dictionary to JSON
data_json = json.dumps(data)

# Create a post
r = requests.post('http://paathsala-plugin.test/wp-json/wp/v2/experience', data = data_json, headers = headers )

print(r)
like image 199
Sagar Bahadur Tamang Avatar answered Oct 22 '22 08:10

Sagar Bahadur Tamang


@Peter Foti can you try below function for add meta value in your API.

add_post_meta( <value>, <name>, $meta_value ,true );

For Reference see this Link

like image 44
Sujal Patel Avatar answered Oct 22 '22 09:10

Sujal Patel