1

I'm using V2.0 and trying to create a post using the /posts endpoint.

Here's the payload being sent with my request:

var payload =
   {
     title : "some title",
     format : "link",
     tags: ["tag1", "tag2"],
     categories: ["newsletter"],
     content: "http://someurl.com",
     status: "publish"
   };

The posts are successfully being created and all other fields are added except for the category and tags.

I see that both of them are supposed to take an array of strings. What am I missing here?

Also, I've tried adding both categories and tags that already exist on the site, and brand new ones. both don't work.

2

You are using name in your terms. In default, try to use the existing term id ( in your case, cat ID and tag ID ).

If you see https://plugins.trac.wordpress.org/browser/rest-api/trunk/lib/endpoints/class-wp-rest-posts-controller.php#L918 they will handle your term with sanitize them into non-negative integer using absint. I hope this help.

Here example code to hook rest_insert_{$this->post_type} to create terms ( tags and categories ) and set into post after post ID created by wp_insert_post. Note: tags and category request are in name array as OP sample code.

add_action( 'rest_insert_post', 'wpse220930_rest_insert_post', 1, 3 );
function wpse220930_rest_insert_post( $post, $request, $update = true )
{
    if ( ! empty( $request['tags'] ) )
        wp_set_object_terms( $post->ID, $request['tags'], 'post_tag', $update );

    if ( ! empty( $request['categories'] ) )
        wp_set_object_terms( $post->ID, $request['categories'], 'category', $update );
}
  • But how can i add a term that doesn't yet exist to a post that i create? Basically I want the same functionality as inside of the post create screen, when you can just add new tags to the post – DMTintner Mar 18 '16 at 11:03
  • In the post create screen, the post id have been set up, then it make it easy to set terms before post created. And to create new terms in the same time with create post, I think still not possible. You can create terms in late after post id created ( or before then set it up later into post ). I update my answer how to hook after post id created, and set terms later. – Jevuska Mar 18 '16 at 13:09
0

Your array should look something like this:

var payload =
   {
     title : "some title",
     format : "link",
     tags: [1,2],
     categories: [3],
     content: "http://someurl.com",
     status: "publish"
   };

The numbers 1 and 2 reference the tags with the ID 1 and 2 and likewise 3 calls the category with the ID 3.

I assume you don't want to reference only existing Tags and Categories, so you would have to first create them.

The following function uses an array that includes your tag names (tag 1 and tag 2) and posts it to the /wp-json/wp/v2/tags endpoint. If the tag already exists, it returns the ID of that tag. If the tag doesn't exist, then it creates a new tag and returns the ID of it.

postID is the ID of the post you want to add the tags to.

  function getTagIDs(postID) {
    let tagNames = [tag 1, tag 2];
    let answers = tagNames.length;
    let receivedAnswers = 0;
    let tagIDList = [];
    $.each(tagNames, function(i, tagName) {
      let tagArguments = {
        'name': tagName
      };
      let createPost = new XMLHttpRequest();
      let postURL = phpVariables.siteBaseURL + '/wp-json/wp/v2/tags';
      createPost.open('POST', postURL);
      createPost.setRequestHeader('X-WP-Nonce', phpVariables.nonce);
      createPost.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
      createPost.onreadystatechange = function() {
        if (this.readyState === 4) {
          receivedAnswers++;
          responseText = JSON.parse(this.responseText);
          if (this.status === 400) {
          tagID = responseText.data.term_id;
          } else {
          tagID = responseText.id;
          }
          tagIDList.push(tagID);
          if (answers == receivedAnswers)
            PostToWpApi(postID, tagIDList);
        }
      };
      createPost.send(JSON.stringify(tagArguments));
    });
  };

Only after the function has saved all the tag IDs into the array tagIDList, will it execute another function called PostToWpApi.

  function PostToWpApi(postID, tagIDs) {
    let postMetaData = {
      'tags': tagIDs,
    };
    let createPost = new XMLHttpRequest();
    let postURL = phpVariables.siteBaseURL + '/wp-json/wp/v2/posts/' + postID;
    createPost.open('POST', postURL);
    createPost.setRequestHeader('X-WP-Nonce', phpVariables.nonce);
    createPost.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    createPost.send(JSON.stringify(postMetaData));
  };

I assume you have already done so, but for anyone else reading this, let me also explain where the phpVariables.siteBaseURL and phpVariables.nonce come from.

Those variables were first generated in PHP and made accessible to JS via wp_localize_script.

In whichever PHP file you enqueued your JS, you should also add the following:

public function enqueue(){
 wp_enqueue_script('scripthandle', 'urltoscript.com/script.js');
 wp_localize_script( 'scripthandle', 'phpVariables', array(
  'nonce' => wp_create_nonce( 'wp_rest' ),
  'siteBaseURL' => get_site_url(),
 ));
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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