How to Change Default Tag Meta Box: Make It like Category Meta Box

Do you want to display all post tags at once on the post edit page? I will show you how to make this replacement in two easy steps.

#taxonomies, #wp-admin  /   14

Let me show you what I mean:

Tags like categories on the post edit page

As you can see the new meta box displays all tags at once. Why do we need this replacement? Dunno, maybe it is more usable for some of us. Also you can do more things with jQuery.

I will show you how to make this replacement in two easy steps. Just insert the code from the first and the second step into your functions.php file and everything should work.

Tags which are already attached to posts will be saved, multi tag selecttion is supported.

Step 1. Remove the Old Tags Meta Box

To create the new one, we need to destroy the old one. Just because WordPress doesn’t support filters and actions which allow to change the metabox content. Also we must not change the WordPress core files.

/*
 * Meta Box Removal
 */
function rudr_post_tags_meta_box_remove() {
	$id = 'tagsdiv-post_tag'; // you can find it in a page source code (Ctrl+U)
	$post_type = 'post'; // remove only from post edit screen
	$position = 'side';
	remove_meta_box( $id, $post_type, $position );
}
add_action( 'admin_menu', 'rudr_post_tags_meta_box_remove');

Step 2. Create the New One, But Looking Like the Categories Meta Box

I use only 3 WordPress functions:

  • add_meta_box(),
  • get_terms() — to get all existing tags,
  • get_the_terms() — to get all tags assigned to post.

This is the code:

/*
 * Add
 */
function rudr_add_new_tags_metabox(){
	$id = 'rudrtagsdiv-post_tag'; // it should be unique
	$heading = 'Tags'; // meta box heading
	$callback = 'rudr_metabox_content'; // the name of the callback function
	$post_type = 'post';
	$position = 'side';
	$pri = 'default'; // priority, 'default' is good for us
	add_meta_box( $id, $heading, $callback, $post_type, $position, $pri );
}
add_action( 'admin_menu', 'rudr_add_new_tags_metabox');
 
/*
 * Fill
 */
function rudr_metabox_content($post) {  
 
	// get all blog post tags as an array of objects
	$all_tags = get_terms( array('taxonomy' => 'post_tag', 'hide_empty' => 0) ); 
 
	// get all tags assigned to a post
	$all_tags_of_post = get_the_terms( $post->ID, 'post_tag' );  
 
	// create an array of post tags ids
	$ids = array();
	if ( $all_tags_of_post ) {
		foreach ($all_tags_of_post as $tag ) {
			$ids[] = $tag->term_id;
		}
	}
 
	// HTML
	echo '<div id="taxonomy-post_tag" class="categorydiv">';
	echo '<input type="hidden" name="tax_input[post_tag][]" value="0" />';
	echo '<ul>';
	foreach( $all_tags as $tag ){
		// unchecked by default
		$checked = "";
		// if an ID of a tag in the loop is in the array of assigned post tags - then check the checkbox
		if ( in_array( $tag->term_id, $ids ) ) {
			$checked = " checked='checked'";
		}
		$id = 'post_tag-' . $tag->term_id;
		echo "<li id='{$id}'>";
		echo "<label><input type='checkbox' name='tax_input[post_tag][]' id='in-$id'". $checked ." value='$tag->slug' /> $tag->name</label><br />";
		echo "</li>";
	}
	echo '</ul></div>'; // end HTML
}

You can use this code not only for the tags but also for any non-hierarchical taxonomy.

Only the best of WordPress

Subscribe to this weekly newsletter to receive the latest blog posts by email.I respect your privacy. Your email is safe with me.

Related Posts

Comments 14

  • Hello

    This is amazing and just what I was looking for – works great!. I have two more custom post types I’d like to effect and I have been trying to add them as an array:

    $post_type array = ('post','people','press_release');

    But nothing I try works. I’m looking to change the Tag meta box for all three of my post types. Any ideas? Really stuck now : [

  • A hah – I thought there might be a neater way, but yes I repeated the entire code three times replacing the post type annd calling your functions rudr, rudr2 and rudr3… thanks for the tip!

  • Miriam de Paula June 2, 2016 at 14:59

    I tried to adapt your code to recreate the category box and could not save the data. When I save the post, the categories are not saved. What can it be?

    function raps_lideres_cidades_meta_box_remove() {
        $id = 'cidadediv'; // you can find it in a page source code (Ctrl+U)
        $post_type = 'lider'; // remove only from post edit screen
        $position = 'side';
        remove_meta_box( $id, $post_type, $position );
    }
    add_action( 'admin_menu', 'raps_lideres_cidades_meta_box_remove');
     
    function raps_lideres_cidades_new_metabox(){
        $id = 'cidadediv'; // it should be unique
        $heading = 'Cidades'; // meta box heading
        $callback = 'raps_lideres_cidades_new_metabox_content'; // the name of the callback function
        $post_type = 'lider';
        $position = 'side';
        $pri = 'default'; // priority, 'default' is good for us
        add_meta_box( $id, $heading, $callback, $post_type, $position, $pri );
    }
    add_action( 'admin_menu', 'raps_lideres_cidades_new_metabox');
     
    function raps_lideres_cidades_new_metabox_content(){
     
        // get all blog post tags as an array of objects
        $all_tags = get_terms('cidade', array('hide_empty' => 0) ); 
     
        // get all tags assigned to a post
        $all_tags_of_post = get_the_terms( $post->ID, 'cidade' );  
     
        // create an array of post tags ids
        $ids = array();
        if ( $all_tags_of_post ) {
            foreach ($all_tags_of_post as $tag ) {
                $ids[] = $tag->term_id;
            }
        }
     
        // HTML
        echo '<div id="'.$id.'" class="postbox">';
        echo '<div class="inside">';
        echo '<input type="hidden" name="tax_input[post_tag][]" value="0" />';
        echo '<ul id="cidade-tabs" class="category-tabs">';
        foreach( $all_tags as $tag ){
            // unchecked by default
            $checked = "";
            // if an ID of a tag in the loop is in the array of assigned post tags - then check the checkbox
            if ( in_array( $tag->term_id, $ids ) ) {
                $checked = " checked='checked'";
            }
            $id = 'cidade-' . $tag->term_id;
            $uf = odin_get_term_meta( $tag->term_id, 'cidade_uf' );
            echo "<li id='{$id}'>";
            echo "<label><input type='checkbox' name='tax_input[post_tag][]' id='in-$id'". $checked ." value='$tag->slug' /> $tag->name (". $uf .")</label><br />";
            echo "</li>";
        }
        echo '</ul></div></div>'; // end HTML
     
    }
    • MishaAuthor June 3, 2016 at 03:51

      Hello Miriam,
      The first thing that I can suggest you is to make the following replacements in your code:

      Replace this line

      echo '<input type="hidden" name="tax_input[post_tag][]" value="0" />';

      with:

      echo '<input type="hidden" name="tax_input[cidade][]" value="0" />';

      You’re not working with post tags! You’re working with the custom taxonomy. So, the next replacement is

      echo "<label><input type='checkbox' name='tax_input[post_tag][]' id='in-$id'". $checked ." value='$tag->slug' /> $tag->name (". $uf .")</label><br />";

      to

      echo "<label><input type='checkbox' name='tax_input[cidade][]' id='in-$id'". $checked ." value='$tag->slug' /> $tag->name (". $uf .")</label><br />";

      I hope it helps.

  • Hello

    thanks for this great tutorial!

    I would like to use this to setup metabox to show only 3 specific tags:

    Featured / Promoted / Ticker

    So user can chose one or all of this three tags.

    Regards :)

  • Hello
    do you think its ready for the newest version, 4.6.3
    By pasting your code in my functions.php i see only the Boxes but no text.

    When i turn on wp_debug here are the error messages:
    Notice: Trying to get property of non-object in \test.de\wp-content\themes\twentysixteen\functions.php on line 515
    Notice: Trying to get property of non-object in \test.de\wp-content\themes\twentysixteen\functions.php on line 518
    Notice: Trying to get property of non-object in \test.de\wp-content\themes\twentysixteen\functions.php on line 520

    these are the lines 515-520:

    if ( in_array( $tag->term_id, $ids ) ) {
    			$checked = " checked='checked'";
    		}
    		$id = 'post_tag-' . $tag->term_id;
    		echo "<li id='{$id}'>";
    		echo "<label><input type='checkbox' name='tax_input[post_tag][]' id='in-$id'". $checked ." value='$tag->slug' /> $tag->
  • thanks for your fast reply!
    Yes there are…

    But
    I have tested now with an clean installation and there it works fine.
    So the fault is on my side

    • MishaAuthor October 27, 2016 at 07:49

      Before making this check:

      if ( in_array( $tag->term_id, $ids ) ) {

      try to look what is $tag, just with this line of code:

      print_r( $tag );
  • Hi, thanks for the code.
    I want to implement it in the frontend, so that a user when publishing a post chooses the existing tags.
    Could you implement it?
    Sorry for my english

    • MishaAuthor May 9, 2017 at 23:40

      Hi Roland,

      no, I have no ready code for this but if you want to allow users to select multiple tags + search by them, I recommend you to look at Select2 jQuery plugin.

  • hi,

    can you please show the reverse situation? from category to tag?

Leave your question or feedback

phpjsHTMLCSSSQLCode
Please, enter a comment
Please, enter a name
Incorrect email