What's an effective way of removing all the meta boxes for a specific post type in Wordpress?

The only solution for removing metaboxes at all that I've found seems to be the remove_meta_box() function, which requires an id of the metabox to be removed. I could remove all the default metaboxes like this, it would be a little fiddly but not impossible or that hard.

However, how would I go about consistently removing the meta boxes added plugins or theme functions elsewhere? Those are dynamic and unpredictable, maybe I can reliably get a summary of the meta boxes for a custom post types edit page and maybe work from there?

  • 1
    Do you want to permanently remove the metaboxes or hide them? – birgire Feb 2 '15 at 15:15

If you want to hide all the metaboxes for all users, you can do that through the get_user_option_metaboxhidden_{cpt}, default_hidden_meta_boxes or the hidden_meta_boxes filter, according to the /wp-admin/includes/screen.php file.

Here's an example for the post post type:

 * Hide all metaboxes in the global $wp_meta_boxes

add_filter( 'hidden_meta_boxes', function( $hidden, $screen, $use_defaults )
    global $wp_meta_boxes;
    $cpt = 'post'; // Modify this to your needs!

    if( $cpt === $screen->id && isset( $wp_meta_boxes[$cpt] ) )
        $tmp = array();
        foreach( (array) $wp_meta_boxes[$cpt] as $context_key => $context_item )
            foreach( $context_item as $priority_key => $priority_item )
                foreach( $priority_item as $metabox_key => $metabox_item )
                    $tmp[] = $metabox_key;
        $hidden = $tmp;  // Override the current user option here.
    return $hidden;
}, 10, 3 );

The source for remove_meta_box() should give you reasonable idea.

The registered boxes are stored in $wp_meta_boxes global. Clearing that global (for example by assigning empty array) will prevent them from shoving.

The only tricky part would be figuring out the correct context and timing. If you do it too early core or some plugin might add metaboxes after. If you do it too late then some will already get into output.


As @rarst said, setting global $wp_meta_boxes to an empty array can be a solution.

Regarding the timing issue, best place to reset the variable is just before it is used. Metaboxes are printed via do_meta_boxes() function and inside it there are no hooks, however it contains

get_user_option( "meta-box-order_$page" )

and get_user_option() fires the filter 'get_user_option_{$option}' so you can use it to perform your cleaning.

Something like this:

function remove_all_metaboxes($type) {
  add_filter("get_user_option_meta-box-order_{$type}", function() use($type) {
      global $wp_meta_boxes;
      $wp_meta_boxes[$type] = array();
      return array();
  }, PHP_INT_MAX);

However the timing problem is not the only one.

The other problem is that if you set $wp_meta_boxes to an empty array all metaboxes are removed, even the core ones, e.g. the box that let you save the post.

So the solution is not to set it to an empty array, but to the array containing the boxes you want to preserve.

E.g. to preserve only the box with publish button, use:

function remove_all_metaboxes($type) {
  add_filter("get_user_option_meta-box-order_{$type}", function() use($type) {
      global $wp_meta_boxes;
      $publishbox = $wp_meta_boxes[$type]['side']['core']['submitdiv'];
      $wp_meta_boxes[$type] = array(
        'side' => array('core' => array('submitdiv' => $publishbox))
      return array();
  }, PHP_INT_MAX);

add_action('admin_init', function() {
  // replace with the slug of the post type you want to target

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.