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?
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?
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 )
{
//Keep the ones that are wanted
if(! in_array($metabox_key,array("submitdiv")))
{
$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
remove_all_metaboxes('post');
});