How to Use wp_insert_post tax_input

Posted Mar 3, 2014

The wpinsertpost() function makes it easy to insert a new post into your WordPress database, so we use it in our Video Importer plugin. Constructing a $post array is pretty easy, but a few of the elements can be tricky. Today I'll be teaching you how to use tax_input to save custom taxonomies when inserting a post.

We're going to start with a simple post array. It contains the post's content, title, and a $custom_tax variable that we'll be using to set all of our custom taxonomy data.

$post = array(
    'post_content' => 'This will be the content.',
    'post_title'   => 'Hello World!',
    'tax_input'    => $custom_tax
);

$post_id = wp_insert_post( $post );

Obviously if we try to run this right now, we'll have a problem because we haven't set our $custom_tax data, so let's do that next.

$custom_tax = array(
    'color' => array(
        'Red',
        'Green',
        'Blue'
    )
);

In the example above we're using a non-hierarchical custom taxonomy named "color" and adding Red, Green, and Blue.

Now if we put it all together we get the following:

$custom_tax = array(
    'color' => array(
        'Red',
        'Green',
        'Blue'
    )
);

$post = array(
    'post_content' => 'This will be the content.',
    'post_title'   => 'Hello World!',
    'tax_input'    => $custom_tax
);

$post_id = wp_insert_post( $post );

This should give you a basic understanding of how it works, so next we'll move into some more advanced ways to use tax_input.

Multiple Custom Taxonomies

We can easily use more than one custom taxonomy by expanding our $customtax array to include as many taxonomies as we need. Just create another key with the name of the taxonomy and set the value to an array of items you'd like to add. In the example below we've modified our original $customtax array to include some items for the "size" custom taxonomy.

$custom_tax = array(
    'color' => array(
        'Red',
        'Green',
        'Blue'
    ),
    'size' => array(
        'Small',
        'Medium',
        'Large'
    )
);

Hierarchical vs. Non-Hierarchical Custom Taxonomies

When registering a custom taxonomy in WordPress, it must be either hierarchical or non-hierarchical. Hierarchical taxonomies are like categories, which means items can have parent items and form a tree. This is useful for things like genres (Indie could be a child of Rock), locations (San Francisco could be a child of California), or anything where one group falls into another. Non-hierarchical taxonomies are like tags, where terms are simply saved to a post and don't have parents. This would be used for things like people, teams, or colors.

We've been using non-hierarchical taxonomies so far, so what do we do if we want to use hierarchical ones? Rather than just using the names in tax_input, we need to use the term IDs. In our next example we're going to add some location data to our post using a hierarchical "location" taxonomy with cities belonging to their parent state. If we were to simply use the city and state names, we would end up with a mess of cities and states that wouldn't make much sense. We'd also run into problems when multiple states have cities with the same name. What we need to do is use IDs to make sure cities are saved with their correct state as the parent. Take a quick look then we'll explain what we're doing.

$city = 'Columbus';
$state = 'Ohio';

// Check if the state exists
$state_term = term_exists( $state, 'location', 0 );

// Create state if it doesn't exist
if ( !$state_term ) {
    $state_term = wp_insert_term( $state, 'location', array( 'parent' => 0 ) );
}

// Check if the city exists
$city_term = term_exists( $city, 'location', $state_term['term_taxonomy_id'] );

// Create city if it doesn't exist
if ( !$city_term ) {
    $city_term = wp_insert_term( $city, 'location', array( 'parent' => $state_term['term_taxonomy_id'] ) );
}

$custom_tax = array(
    'location' => array(
        $state_term['term_taxonomy_id'],
        $city_term['term_taxonomy_id']
    )
);

$post = array(
    'post_content' => 'This will be the content.',
    'post_title'   => 'Hello World!',
    'tax_input'    => $custom_tax
);

$post_id = wp_insert_post( $post );

Once we've specified our city and state, we need to check if the state already exists in WordPress. The termexists() function checks if a term already exists and returns the data if it does. By setting the last argument to "0" we're only checking for terms without a parent, which would make sure it is a state. If the state doesn't exist, we're using wpinsert_term() to add it to the WordPress database.

Now that we have the state figured out, we repeat the process for the city with one small change. Instead of using "0" as the parent ID in termexists(), we're going to use the state's ID to make sure we're getting the correct city. If the city hasn't been created for that state, we'll also need to specify the state ID in wpinsert_term().

Now that we know we have the correct city and state data stored as terms, we just need to use their IDs in our $custom_tax array. This method could be expanded to include countries, or applied to something entirely different like genres.

Common Problems & More Info

One common issue is that the user must have the capability to use the specified custom taxonomy. If you're running into problems where this might be the cause, try this solution.

You can check out the wpinsertpost() function reference for more info on constructing a $post array.

How are you using wp_insert_post tax_input?

Let us know how you're using taxinput with wpinsert_post and feel free to leave a comment if you have any questions.