2

I have a post type with 7 (count it SEVEN!) taxonomy tag boxes. By default, the only options to display these metaboxes are - 7 small metaboxes on the right side stacking or turn these tag metaboxes into Long metaboxes and stack them below the main editor.

What I'd rather do is bring all the metaboxes into 1 big metabox below the editor, stacking them in a 3x3 grid (really it would be 3 per row with 1 remainder).

My question is when it comes to metaboxes that WordPress creates do I have any control on how or where it is displayed? Is it possible to group these metaboxes in some way?

Post Type / Taxonomy Registers

// Products Custom Post Type
register_post_type( 'cpt_products', array(
    'labels'            =>  array(
        'name'          =>      __( 'Products' ),
        'singular_name' =>      __( 'Product' ),
        'all_items'     =>      __( 'View Products' ),
        'add_new'       =>      __( 'New Product' ),
        'add_new_item'  =>      __( 'New Product' ),
        'edit_item'     =>      __( 'Edit Product' ),
        'view_item'     =>      __( 'View Product' ),
        'search_items'  =>      __( 'Search Products' ),
        'no_found'      =>      __( 'No Products Found' ),
        'not_found_in_trash' => __( 'No Products in Trash' )
                            ),
    'public'            =>  true, 
    'show_ui'           =>  true, 
    'query_var'         =>  false,
    'show_in_nav_menus' =>  false,
    'capability_type'   =>  'post',
    'hierarchical'      =>  false,
    'menu_position'     =>  20,
    'menu_icon'         =>  'dashicons-cart',
    'has_archive'       =>  'products',
    'rewrite'           =>  array( 'slug' => 'product', 'with_front' => false ),
    'supports'          =>  array( 'title','editor','thumbnail','page-attributes' )
));

// Testing Taxonomy for Products
register_taxonomy( 'tax_testing', 'cpt_products', array(
    'labels'            =>  array(
        'name'                      =>  __( 'Test' ),
        'singular_name'             =>  __( 'Test' ),
        'menu_name'                 =>  __( 'View Test' ),
        'all_items'                 =>  __( 'All Test' ),
        'edit_item'                 =>  __( 'Edit Test' ),
        'view_item'                 =>  __( 'View Test' ),
        'update_item'               =>  __( 'Update Test' ),
        'add_new_item'              =>  __( 'New Test' ),
        'new_item_name'             =>  __( 'Rename Test' ),
        'parent_item'               =>  __( 'Parent Test' ),
        'parent_item_colon'         =>  __( 'Parent Test:' ),
        'search_items'              =>  __( 'Search Test' ),
        'popular_items'             =>  __( 'Popular Test' ),
        'seperate_items_with_commas'=>  __( 'Separate Test with commas' ),
        'add_or_remove_items'       =>  __( 'Add or remove Test' ),
        'choose_from_most_used'     =>  __( 'choose from most used Test' ),
        'not_found'                 =>  __( 'No Test found.' )
    ),
    'show_ui'           =>  true,
    'show_admin_column' =>  true,
    'sort'              =>  true,
    'rewrite'           =>  array( 'slug' => 'products/test', 'with_front' => false )
));

2 Answers 2

2

Register your taxonomies with 'show_ui' => false, and then add a single meta box to manage them.

function create_book_tax() {
        register_taxonomy(
                'genre',
                'book',

                array(
                        'label' => __( 'Genre' ),
                        'rewrite' => array( 'slug' => 'genre' ),
                        'hierarchical' => true,
                        'show_ui' => false,
                )
        );
}

Or unhook the boxes from the side panel and put them below the main editor (using a post type and tax form the docs).

add_action(
  'add_meta_boxes_book',
  function () {
    remove_meta_box( 'genrediv', 'book', 'side' ); 

    $tax_name = 'genre';
    $taxonomy = get_taxonomy( $tax_name );

    $label = $taxonomy->labels->name;
    $tax_meta_box_id = $tax_name . 'div';

    add_meta_box( 
      $tax_meta_box_id, 
      $label, 
      $taxonomy->meta_box_cb
    ); 
  }
);

A third option is to create your own set of meta box containers and add your boxes to those.

add_action(
  'add_meta_boxes_book',
  function () {
    remove_meta_box( 'genrediv', 'book', 'side' );
  }
);

add_action(
  'dbx_post_sidebar',
  function ($post) {

    $tax_name = 'genre';
    $taxonomy = get_taxonomy( $tax_name );

    $label = $taxonomy->labels->name;
    $tax_meta_box_id = $tax_name . 'div';

    add_meta_box( 
      $tax_meta_box_id, 
      $label, 
      $taxonomy->meta_box_cb,
      'book',
      'mycol1'
    ); 

    echo 'my boxes'; //debug
    do_meta_boxes('book', 'mycol1', $post);
    do_meta_boxes('book', 'mycol2', $post);
    do_meta_boxes('book', 'mycol3', $post);
    echo 'end my boxes'; //debug
  }
);

If you look at the source you will see that the containers you created are surrounded by divs with the mycol*-sortables id. You should be able to use that to create the columns you are after.

7
  • IIRC once you remove a core meta box you can't re-add them therefor you will need to probably use different ids, and I have no idea if it has any impact on the JS code making the AJAX requests. Oct 24, 2014 at 17:23
  • 1
    This code works for me when I run it, @MarkKaplun. The metabox dissappears and then comes back below the editor.
    – s_ha_dum
    Oct 24, 2014 at 17:26
  • 1
    @MarkKaplun only reason that removing a core meta box and re-adding it causes problem is when the addition happen is a separate function before the removing, if used like s_ha_dum did, there is no problem at all.
    – gmazzap
    Oct 24, 2014 at 17:42
  • @G.M., always learn something new :) Now I need to recheck that code that didn't work for me and see what have I done differently there. Oct 24, 2014 at 18:08
  • @s_ha_dum Thanks for the suggestion, I tried the second code block in the context of multiple metaboxes (See Code) but it just added them below the editor stacked. My goal is to add the 7 metaboxes into 1 metabox in a 3x3 grid which leads me to believe I would need to add the metabox in a Original metabox callback. You mention > then add a single meta box to manage them. - Is there a way to add these but keep the same functionality of tag-clouds and smart-type?
    – Howdy_McGee
    Oct 24, 2014 at 18:52
2

Edit

Code in this answer has issue with non-hierarchical taxonomies for custom post types.

For core post types (post, page) it works for both hierarchical and non hierarchical taxonomies. For CPT it works only for hierarchical taxonomies.

Issue seems to be related to javascript, and I don't really want to dig in WP javascript code to solve it.


This answer uses the same approach of @s_ha_dum but uses core functions get_taxonomies, post_categories_meta_box and post_tags_meta_box to output a single metabox, that being same functions used by core assure compatibility with any 3rd party code and avoid additional work i.e. to check if the user has capability to add terms and so on.

As bonus it works dynamically for all taxonomies without any additional effort.

Taxonomies big metabox

add_action( 'add_meta_boxes', 'my_taxonomies_meta_box', 10, 2 );

function my_taxonomies_meta_box( $post_type, $post ) {

  // all public taxonomies for current post type
  $taxs = get_taxonomies(
    array( 'object_type' => array( $post_type ), 'show_ui' => true )
  );
  
  $output = '<div>';
  
  foreach ( $taxs as $tax ) {
  
    $i = ! isset($i) ? 1 : $i + 1;
  
    $cb = 'post_categories_meta_box';
    $id = "{$tax}div";
  
    // set callback and id for non-hierarchical taxonomies
    if ( ! is_taxonomy_hierarchical( $tax ) ) {
      $cb = 'post_tags_meta_box';
      $id = "tagsdiv-{$tax}";
    }
  
    remove_meta_box( $id, $post_type, 'side' ); // remove core metabox 
  
    $tax_obj = get_taxonomy( $tax );
    $args = array(
      'args' => array( 'taxonomy' => $tax ), 'title' => $tax_obj->labels->name
    );
  
    // add a 1/3 wide div with tax metabox
    $format = '<div id="%s" class="postbox" style="%s">';
    $output .= sprintf( $format, $id, 'padding:8px;width:30%;margin:1%;float:left;' );
  
    $output .= '<h3>' . $tax_obj->labels->name . '</h3>';
    ob_start();
    call_user_func( $cb, $post, $args );
    $output .= ob_get_clean(). '</div>';
  
    if ( ( $i !== 0 && $i%3 === 0 ) || $i === count( $taxs ) ) {
      $output .= '<div style="width:100%;clear:both;"></div>';
    }

  } // end foreach

  $output .= '</div><div style="width:100%;clear:both;"></div>';
  
  // add a callback that will output all the markup generated
  add_meta_box( 'all_taxonomies', __('Taxonomies'), function() use( $output ) {
    echo $output;
  }, $post_type, 'normal', 'high' );

} // end function
10
  • This is exactly what I was looking for! Currently though it doesn't seem to remove the core metaboxes. Taxonomy Tag metaboxes are have an ID of tagsdiv-tax_books and the ID you save to remove the metabox would be tax_booksdiv at the top of your foreach. That's the only edit I could see. Thanks!
    – Howdy_McGee
    Oct 24, 2014 at 19:11
  • Well it doesn't seem like the metaboxes save :/ - so while adding them to the single metabox we've lost the functionality unless I've copied something wrong. There's no JS errors but I imagine the ajax isn't picking it up - $_POST isn't picking it up either.
    – Howdy_McGee
    Oct 24, 2014 at 19:36
  • Hmmm... Whenever I paste the new code I get the same result. Nothing in my debug or in my JS console.
    – Howdy_McGee
    Oct 24, 2014 at 20:23
  • Really strange! The screenshot in the answer is taken in my local environment where I tested the code and it worked without any issue... @Howdy_McGee
    – gmazzap
    Oct 24, 2014 at 20:25
  • I see, it works on the built in types but not custom types. For example, both yours and @s_ha_dum code works on post but not on a custom post type of post. I've edited my question to show what I'm passing to register my taxonomy and post type but I'll keep looking into why it would work on 1 post type but not a custom.
    – Howdy_McGee
    Oct 24, 2014 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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