I have code comments about three solutions already posted, but also a general comment
They present a suboptimal choice: either override the user's Screen Options checkbox choice; or respect it but have your code ignored if the user has ever changed the checkboxes, even for other meta_boxes, or before your code was in WP. Seems the respectful choice is only useful if all your users are new. The best solution would be to set a custom user option to determine if your specific meta_box defaults have been changed by the user, and respect that. No, I haven't written that code! Should be easy... :)
The three solutions posted:
1. WraithKenny's hidden_meta_boxes
solution is the one that overrides the user_option. Note it covers all post types ('post', 'page', 'link', 'attachment', and any custom post types). That's fine unless you want it to be specific. You specified the post_type's in your add_meta_box()
calls. You can try to match those, or just wing it since the ones that don't match will be ignored. If you want to know the post_type in the filter, you can use the extra screen
parameter:
add_filter('hidden_meta_boxes', 'foo_hidden_meta_boxes', 10, 2);
function foo_hidden_meta_boxes($hidden, $screen) {
$post_type= $screen->id;
switch ($post_type) {
// case 'post', 'page', 'link', 'attachment', and any custom post types
// $hidden[]= 'foo_box_id';
// /or/
// $hidden= array_diff($hidden, array('foo_box_id'));
}
return $hidden;
}
2. As Rarst says, default_hidden_meta_boxes
respects the user_option. As with hidden_meta_boxes
, you can use the $screen parameter to distinguish post_types.
3. Drebabels's set_user_metaboxes() function also respects the user_option. Note it is hard-coded for the 'post' edit screen. To handle the 'page' edit screen, and other post_types, wrap the code in this loop:
function set_user_metaboxes($user_id=NULL) {
$post_types= array( 'post', 'page', 'link', 'attachment' );
// add any custom post types here:
// $post_types[]= 'my_custom_post_type';
foreach ($post_types as $post_type) {
// These are the metakeys we will need to update
$meta_key= array(
'order' => "meta-box-order_$post_type",
'hidden' => "metaboxhidden_$post_type",
);
// The rest is the same as drebabels's code,
// with '*_user_meta()' changed to '*_user_option()'
// So this can be used without hooking into user_register
if ( ! $user_id)
$user_id = get_current_user_id();
// Set the default order if it has not been set yet
if ( ! get_user_option( $meta_key['order'], $user_id ) ) {
$meta_value = array(
'side' => 'submitdiv,formatdiv,categorydiv,postimagediv',
'normal' => 'postexcerpt,tagsdiv-post_tag,postcustom,commentstatusdiv,commentsdiv,trackbacksdiv,slugdiv,authordiv,revisionsdiv',
'advanced' => '',
);
update_user_option( $user_id, $meta_key['order'], $meta_value, true );
}
// Set the default hiddens if it has not been set yet
if ( ! get_user_option( $meta_key['hidden'], $user_id ) ) {
$meta_value = array('postcustom','trackbacksdiv','commentstatusdiv','commentsdiv','slugdiv','authordiv','revisionsdiv');
update_user_option( $user_id, $meta_key['hidden'], $meta_value, true );
}
}
}
Yeah, get_user_meta
should be get_user_option
. For single-site it doesn't matter, and even for multi-site it probably doesn't. See wp-admin/includes/ajax-actions.php for why: update_user_option
has the 'true' global parameter.