Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Custom taxonomies are great. I registered a bunch of new taxonomies and wrote an importer to import our hierarchical taxonomy into WordPress a la XML. The problem is one taxonomy has about 1,100 terms and browsing a checklist of 1,100 things is cruel and unusual punishment.

Is there any way to have a hierarchical taxonomy but use the Tag interface (search box with auto complete) instead?

Update: this code from Bainternet's answer gets most of the way there (adds tag interface for the specified taxonomy, with working autocomplete and correctly populated "most used" tag cloud), but terms are not saved on post save. If the post had terms before, they will be deleted on save. So I am still looking for an answer. (This same code saves terms just fine if the taxonomy is registered with hierarchichalset to false, but the point of the question is to use the tag interface on a hierarchical taxonomy.)

//remove default metabox
//change TAXONOMY_NAME to your taxonomy name
add_action( 'admin_menu' , 'remove_post_custom_fields' );
function remove_post_custom_fields() {
    remove_meta_box( 'issuediv' , 'post' , 'normal' ); 
}



//add our custom meta box
add_action( 'add_meta_boxes', 'my_add_custom_box' );

 function my_add_custom_box() {
    add_meta_box( 
//      'myplugin_sectionid',
        'tagsdiv-issue',
        __( 'New and Improved Issue Tags', 'textdomain' ),
        'tags_like_custom_tax',
        'post' 
    );
 }

 //call back function to display the metabox
 //change TAXONOMY_NAME to your taxonomy name 
 function tags_like_custom_tax(){
     $tax_name = 'issue';
     global $post;
     $taxonomy = get_taxonomy($tax_name);
     $disabled = !current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '';
     ?>
     <div class="tagsdiv" id="<?php echo $tax_name; ?>">
        <div class="jaxtag">
            <div class="nojs-tags hide-if-js">
                <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
                <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php echo $disabled; ?>><?php echo get_terms_to_edit( $post->ID, $tax_name ); // textarea_escaped by esc_attr() ?></textarea>
            </div>
            <?php if ( current_user_can($taxonomy->cap->assign_terms) ) { ?>
            <div class="ajaxtag hide-if-no-js">
                <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->name; ?></label>
                <div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
                <p><input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
                <input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" /></p>
            </div>
            <p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
            <?php } ?>
        </div>
        <div class="tagchecklist"></div>
    </div>
          <?php if ( current_user_can($taxonomy->cap->assign_terms) ) { ?>
            <p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
          <?php } 
}

The original question is borrowed from the Wordpress forum post here.

share|improve this question

3 Answers 3

up vote 1 down vote accepted
+50

Here's how I did it. Just add a conditional that checks if the page being loaded is an admin page or not. If it is an admin page, set hierarchical to false, otherwise set hierarchical to true. Like so:

$args = array( 
    'hierarchical' => true,
    'labels' => $labels,
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => array( 
          'slug' => 'genre'
    ), 
 )

if( is_admin() ) {
    $args['hierarchical'] = false;
}

register_taxonomy('genre', array('book'), $args);

That should give you the idea. The downside to this is you can't add parent relationships to terms using the admin interface. You could get more specific in the is_admin() conditional such as looking to see if the request contains post-new.php or post.php

share|improve this answer
    
Can this be done even if taxonomies are defined via a plugin and not manually? –  pax Oct 6 at 20:59

The only way i have found is to remove the default metabox and create your own, here is the code i have used:

//remove default metabox
//change TAXONOMY_NAME to your taxonomy name
add_action( 'admin_menu' , 'remove_post_custom_fields' );
function remove_post_custom_fields() {
    remove_meta_box( 'TAXONOMY_NAMEdiv' , 'post' , 'normal' ); 
}



//add our custom meta box
add_action( 'add_meta_boxes', 'my_add_custom_box' );

 function my_add_custom_box() {
    add_meta_box( 
        'myplugin_sectionid',
        __( 'My Taxonomy Section Title', 'textdomain' ),
        'tags_like_custom_tax',
        'post' 
    );
 }

 //call back function to display the metabox
 //change TAXONOMY_NAME to your taxonomy name 
 function tags_like_custom_tax(){
     $tax_name = 'TAXONOMY_NAME';
     global $post;
     $taxonomy = get_taxonomy($tax_name);
     $disabled = !current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '';
     ?>
     <div class="tagsdiv" id="<?php echo $tax_name; ?>">
        <div class="jaxtag">
            <div class="nojs-tags hide-if-js">
                <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
                <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php echo $disabled; ?>><?php echo get_terms_to_edit( $post->ID, $tax_name ); // textarea_escaped by esc_attr() ?></textarea>
            </div>
            <?php if ( current_user_can($taxonomy->cap->assign_terms) ) { ?>
            <div class="ajaxtag hide-if-no-js">
                <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
                <div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
                <p><input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
                <input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" /></p>
            </div>
            <p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
            <?php } ?>
        </div>
        <div class="tagchecklist"></div>
    </div>
          <?php if ( current_user_can($taxonomy->cap->assign_terms) ) { ?>
            <p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
          <?php } 
}

As for saving, you don't need to worry about it, WordPress does that for you.

Update, I just tested it with categories and it works fine:

enter image description here

share|improve this answer
    
Exactly what i would have done(remove metabox -> add a custom one). +1 –  t31os Aug 16 '11 at 17:31
    
@Bainternet The tag interface is rendered perfectly (autofills existing terms, tag cloud is correct, etc), but when I save the post, tags are not saved and all tags that were previously tagged are removed. Ideas? –  supertrue Aug 17 '11 at 5:01
    
no, i need to see your setup, but it's working fine on my end –  Bainternet Aug 17 '11 at 5:44
    
I think it must be something in the code; I tried this on a fresh WP install, and the same thing happens. Is there a missing instance of TAXONOMY_NAME or something? Here's the code: gist.github.com/1151032 —that uses a custom taxonomy, but I also tried with the category taxonomy. –  supertrue Aug 17 '11 at 7:45
    
i updated my answer –  Bainternet Aug 17 '11 at 8:13

I think we can add a hidden input that retrieves the selected tag's term_id via jquery (ajax) and save it as the post's term by using the function wp_set_object_terms

What do you say?

I've posted another question relevant to this problem.

WP native tag suggest metabox. How does it process tag id?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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