admin管理员组

文章数量:1122846

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: "",
     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.

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.

Share Improve this question asked Mar 17, 2016 at 7:55 DMTintnerDMTintner 1111 silver badge4 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 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 );
}

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(),
 ));
}

本文标签: jsonWhy aren39t tags and categories added in post request to WP Rest API