I've roughly followed the tutorial here on how to create "custom taxonomy input panels". I'm using a custom post type of homes and a custom taxonomy called beds (used to record the number of beds in a house). I've got the taxonomy terms showing up in a drop down menu, but cannot get them to save when the post is saved. I started to just post the code that is intended to save the term, but realized that I should post the code that creates and displays the metabox as well, for context. The custom post type name is 'homes' and the custom taxonomy name is 'beds'. The taxonomy is hierarchical (not that I think that matters in this case, but I could be wrong).

//adding metaboxes for the homes post type
function add_homes_metaboxes() {
    add_meta_box( 'blackstone_homes_beds', 'Beds', 'blackstone_homes_beds', 'homes', 'side', 'default' );

function add_homes_menus() {
    if ( !is_admin() )
    add_action( 'admin_menu', 'add_homes_metaboxes' );
    /* Use the save_post action to save new post data */
    add_action( 'save_post', 'save_taxonomy_data' );


function blackstone_homes_beds( $post ) {

    echo '<input type="hidden" name="beds_noncename" id="beds_noncename" value="' .
    wp_create_nonce( 'taxonomy_beds' ) . '" />';

    // Get all theme taxonomy terms
    $beds = get_terms( 'beds', 'hide_empty=0' );
    $stuff = array( 'this', 'that' );
<select name='homes_beds' id='homes_beds'>
    <!-- Display beds as options -->
    $names = wp_get_object_terms( $post->ID, 'beds' );
    <option class='beds-option' value=''
            <?php if ( !count( $names ) )
                echo "selected"; ?>>None</option>
            foreach ( $beds as $bed ) {
                if ( !is_wp_error( $names ) && !empty( $names ) && !strcmp( $bed->slug, $names[0]->slug ) )
                    echo "<option class='beds-option' value='" . $bed->slug . "' selected>" . $bed->name . "</option>\n";
                    echo "<option class='beds-option' value='" . $bed->slug . "'>" . $bed->name . "</option>\n";

        function save_taxonomy_data( $post_id ) {
// verify this came from our screen and with proper authorization.

            if ( !wp_verify_nonce( $_POST['beds_noncename'], 'taxonomy_beds' ) ) {
                return $post_id;

            // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything
            if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
                return $post_id;

            // Check permissions
            if ( 'homes' == $_POST['post_type'] ) {
                if ( !current_user_can( 'edit_page', $post_id ) )
                    return $post_id;
            } else {
                if ( !current_user_can( 'edit_post', $post_id ) )
                    return $post_id;

            // OK, we're authenticated: we need to find and save the data
            $post = get_post( $post_id );
            if ($post->post_type == 'homes'){
                $beds = $_POST['homes_beds'];
                wp_set_object_terms( $post_id, $beds, 'beds' );
            return $beds;

I know there's another very similar question here already, but the solution to it uses the WPAlchemy class, and I'd rather not do so.

Any suggestions on what I might have wrong? I've been staring at this all day, so I fully expect to find out I've just got a variable name off by one character or something.

EDIT: Here's what I changed to get it working correctly:

Instead of echoing the hidden field with the nonce, I used wp_nonce_field( __FILE__, 'taxonomy_beds' ); and when verifying the nonce, I used if ( !wp_verify_nonce( $_POST['taxonomy_beds'], __FILE__ ) )

2 Answers 2


I believe your problem might be nonce-related. I see you're doing what I did at one point with a problem I had when I tried doing nonces the way you're using them.

I'll quote @EAMann on this:

The standard way to create this field is using WordPress' wp_nonce_field() function. It will add the hidden field for you:

wp_nonce_field( __FILE__, 'argus_edit_visitor' );

Try that, see if it works. I don't see anything else wrong with your code.

If that doesn't work, try print_r( $_POST['beds'] ) to reveal what is being submitted in $_POST['beds'].

  • You were exactly right, the nonce was the problem. For posterity, I'm going to edit my question and add the correct usage at the bottom of it. Commented Feb 9, 2011 at 21:55

I don't see the save function hooking into save_post

Try adding this to the end.

add_action( 'save_post' , 'save_taxonomy_data' , 1, 2); 
  • It's there, line 11 of what I posted. See the other answer and my comment - got the problem solved. Commented Feb 9, 2011 at 22:45
  • Doh... I should read the questions more thoroughly.
    – Chris_O
    Commented Feb 9, 2011 at 23:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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