How to set default screen options?

I’d love to be able to hide meta boxes using screen options, instead of removing them or restricting them to user roles, the goal is to just “uncheck” the meta box for the user.

I see how this would be tricky since any code that would make a DB change for a user wouldn’t be allowed to run every time they hit the page because it would just reset. But smarter people than I code the core, so maybe there’s a way. And if there is, I’m dying to know.

Read More

Any ideas?

Related posts

Leave a Reply

4 comments

  1. You are referring to the metaboxes on the admin post screen right?

    For that you don’t need a plugin, just drop the following into your functions.php file.

    // add_action('user_register', 'set_user_metaboxes');
    add_action('admin_init', 'set_user_metaboxes');
    function set_user_metaboxes($user_id=NULL) {
    
        // These are the metakeys we will need to update
        $meta_key['order'] = 'meta-box-order_post';
        $meta_key['hidden'] = 'metaboxhidden_post';
    
        // 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_meta( $user_id, $meta_key['order'], true) ) {
            $meta_value = array(
                'side' => 'submitdiv,formatdiv,categorydiv,postimagediv',
                'normal' => 'postexcerpt,tagsdiv-post_tag,postcustom,commentstatusdiv,commentsdiv,trackbacksdiv,slugdiv,authordiv,revisionsdiv',
                'advanced' => '',
            );
            update_user_meta( $user_id, $meta_key['order'], $meta_value );
        }
    
        // Set the default hiddens if it has not been set yet
        if ( ! get_user_meta( $user_id, $meta_key['hidden'], true) ) {
            $meta_value = array('postcustom','trackbacksdiv','commentstatusdiv','commentsdiv','slugdiv','authordiv','revisionsdiv');
            update_user_meta( $user_id, $meta_key['hidden'], $meta_value );
        }
    }
    

    Basically what is happening is that for the currently logged in user, you are changing some saved meta_values in the wp_usermeta table.

    There are two ways to use this function, you can either hook into ‘user_register’ or you can hook into ‘admin_init’.

    The advantage of using ‘user_register’ is that this function will only fire when a new user is registered (thus lower overhead). However it will not work for users that already exist.

    If you want it to work for users that already exist, then hook into ‘admin_init’. The disadvantage of course is that now this function fires every time a user goes to the admin page.

  2. 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.

  3. add_filter( 'hidden_meta_boxes', 'custom_hidden_meta_boxes' );
    function custom_hidden_meta_boxes( $hidden ) {
        $hidden[] = 'your_metabox';
        return $hidden;
    }
    

    There is also hidden_meta_boxes filter that would “uncheck” the metabox (making it hidden) on every page load (but wouldn’t have to update the database at all). If you just want it off for new users until they check the box themselves, use Rarst’s answer.