7

I'm using the built-in WP REST API to create posts (custom post type). I've got this part working, below is some example JSON I submit to create a new post.

{
 "title": "The story of Dr Foo",
 "content": "This is the story content",
 "status":"publish",
 "excerpt":"Dr Foo story"
}

Problem is, how do I also pass which taxonomies to assign? I can't seem to find a trace of anyone asking or how to do it?

For context, server 1 is creating the posts and WP exists on server 2.

I have also tried passing a long meta data with the request, to which I can then loop over on the WP server and set the taxonomies accordingly with wp_set_post_terms().

To do that, there is this (almost) rest_insert_{$this->post_type} that fires after a single post is created or updated via the REST API.

The problem with this method is that the meta data is not set until AFTER the action_rest_insert_post_type() function has finished. This means that when I try to retrieve the current posts metadata, it doesn't exist.

function action_rest_insert_post_type( $post, $request, $true ) {

   $items = get_post_meta( $post->ID); // at this point in time, returns empty array.

   //wp_set_terms()

}

I have confirmed that $post->ID is working as expected, it's just that the metadata isn't set fully...

Please advise.

James Jones
  • 3,850
  • 5
  • 25
  • 44
ProEvilz
  • 5,310
  • 9
  • 44
  • 74
  • Am I missing something, or should you be able to pass the data and work with it in `action_rest_insert_post_type()` from $request? I haven't come in contact with the rest API yet, but from the documentation, that sounds possible. What meta data were you expecting there? – janh Nov 13 '17 at 14:18
  • @janh That my plan initially.. but as explained above, `get_post_meta()` returns an empty array inside `action_rest_insert_post_type()` because the meta data at that point hasn't finished being set. The meta data expected is just custom fields (taxonomy) data to use to set the taxonomies (since it can't be done in the request it's self) – ProEvilz Nov 13 '17 at 14:20
  • Yeah, but it shouldn't be available as meta data, but in `$request` imho - did you var_export() that variable to see what is available to you? If it isn't, I'm going to try replicating that in a local install. – janh Nov 13 '17 at 14:25
  • It's available in `$request` but `$request` has some type of 'protected' status assigned to it which makes in unaccessible – ProEvilz Nov 13 '17 at 14:26

2 Answers2

15
function action_rest_insert_post( $post, $request, $true ) {
    $params = $request->get_json_params();
    if(array_key_exists("terms", $params)) {
        foreach($params["terms"] as $taxonomy => $terms) {
            wp_set_post_terms($post->ID, $terms, $taxonomy);
        }
    }
}

add_action("rest_insert_post", "action_rest_insert_post", 10, 3);

I've used post, but this shouldn't be any different for custom post types, just change the action it hooks into. This works fine for me when being called with something like this:

{
    "title": "The story of Dr Foo",
    "content": "This is the story content",
    "status":"publish",
    "excerpt":"Dr Foo story",
    "terms": {
        "mytaxonomy": [ "myterm", "anotherterm" ]
    }
}

If you wanted to send that data via POST, you'd need to change way to get the params to

    $params = $request->get_body_params();

and send the data as:

title=testtitle&content=testcotnent&status=publish&excerpt=testexcert&terms[mytaxonomy][]=myterm&terms[mytaxonomy][]=anotherterm

janh
  • 2,885
  • 2
  • 22
  • 21
  • 1
    Thanks. It is sent as post and `get_json_params()` still works fine. I had to also use `wp_set_object_terms()` to get it to work. – ProEvilz Nov 13 '17 at 16:35
  • Six years later, this is still the solution. You should even check $request->get_body(), in case of a "raw" request in JSON. – Bellu Jan 04 '23 at 07:10
1

after a few hours it works for me too... Maybe it helps one or the other, if I post my solution here too

this ist my function based in the functions.php

my posttype called "transaktionen"

function action_rest_insert_transaktionen( $post, $request, $true ) {
    $params = $request->get_json_params();
    if(array_key_exists("terms", $params)) {
        foreach($params["terms"] as $taxonomy => $terms) {
            wp_set_object_terms($post->ID, $terms, $taxonomy, true);
        }
    }
}
add_action("rest_insert_transaktionen", "action_rest_insert_transaktionen", 10, 3);

and thats the json:

{'title': 'Test,
          'status': 'publish',
          'content': 'Text,
          'author': '1',
          'format': 'standard',
           "terms": {"person": ["Test"]}
}