我希望能够使用屏幕选项来隐藏meta框,而不是删除它们或将其限制为用户角色,而是要为用户“取消选中” meta框。

我了解这将是多么棘手的问题,因为任何会导致用户更改数据库的代码都不会在用户每次访问该页面时就运行,因为它们只会重置。但是比我编写核心代码还要聪明的人,所以也许有办法。如果有的话,我很想知道。

有什么想法吗?

评论

对于每个用户名,您将必须创建自己的排序插件,该插件将在所有用户名旁边填充一个复选框,并将其挂接到一个用于显示元框或多个元框的过滤器中。

默认情况下,您是说在创建新用户时应该应用一次,对吗?

#1 楼

您是在指向管理员帖子屏幕上的metabox吗?

为此,您不需要插件,只需将以下内容放到functions.php文件中即可。

// 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 );
    }
}


基本上发生的是,对于当前登录的用户,您正在wp_usermeta表中更改一些已保存的meta_values。

有两种使用此功能的方法,您可以挂钩到“ user_register”,也可以挂钩到“ admin_init”。

使用'user_register'的优点是,仅当注册了新用户时,此函数才会启动(因此开销较低)。但是,它不适用于已经存在的用户。

如果您希望它对已经存在的用户起作用,请转至'admin_init'。当然,缺点是现在用户每次进入管理页面都会触发此功能。

评论


这不是主题工作,不属于functions.php。

– fuxia♦
2011年6月14日下午13:05

@toscho我不太同意。自然地,您可以将其放入插件中,但是,例如,如果您要为自己或某个不需要查看特定框的客户端构建主题,那么为什么要增加将其包含在插件中的额外管理开销。通过将其放到functions.php文件中,可以确保主题的体验是一致的,而不必确保已安装并激活插件。

–drebabels
11年6月29日在12:32

使用插件没有任何开销。这是一个神话,必须立即消失。另外,您的使用限制不是问题的一部分。成千上万的新手会阅读您的答案。您将以最好的代码帮助他们,而不是在某些特定情况下可以起作用的代码。 :)

– fuxia♦
11年6月29日在17:15

+1好答案-有时您确实想明确设置这些值。这是一个很好的基础,当然可以轻松修改此代码以在必要时调用它(例如,添加一个新用户),这样,您实际上是在设置“默认”选项,而不是对更改它们的用户强制使用这些选项。我会将这段代码添加到主题的functions.php文件中,因为默认选项是针对特定项目的,该特定项目由我正在开发的主题表示/容纳。

– cwd
2011年11月3日14:54

在编写此答案的几个月后,将过滤器添加到核心中使该答案过时了。

–幽灵肯尼
13年1月1日在17:05

#2 楼

default_hidden_meta_boxes中有一​​个get_hidden_meta_boxes()过滤器,只要用户未在屏幕选项中修改其首选项,就可以修改不显示的内容。

#3 楼

我已经发布了有关三个解决方案的代码注释,但也有一个一般性注释

,它们给出了一个次优的选择:要么覆盖用户的“屏幕选项”复选框,要么选择“不显示”。或尊重它,但是如果用户更改了复选框(甚至其他meta_box),或者您的代码在WP中之前,也忽略了您的代码。似乎只有在所有用户都是新用户的情况下,尊重的选择才有用。最好的解决方案是设置一个自定义用户选项,以确定用户是否已更改了特定的meta_box默认设置,并遵守了该设置。不,我还没有编写代码!应该很容易... :)

发布的三个解决方案:

1。 WraithKenny的hidden_meta_boxes解决方案是覆盖user_option的解决方案。请注意,它涵盖了所有帖子类型(“帖子”,“页面”,“链接”,“附件”和任何自定义帖子类型)。除非您不希望它具体化,否则很好。您在add_meta_box()调用中指定了post_type。您可以尝试匹配它们,或者只附加它,因为不匹配的将被忽略。如果您想知道过滤器中的post_type,则可以使用额外的screen参数:

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。正如Rarst所说,default_hidden_meta_boxes尊重user_option。与hidden_meta_boxes一样,您可以使用$ screen参数来区分post_types。

3。 Drebabels的set_user_metaboxes()函数也尊重user_option。请注意,它是为“帖子”编辑屏幕进行硬编码的。要处理“页面”编辑屏幕和其他post_type,请将代码包装在此循环中:

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 );
       }
    }
 }


是的,get_user_meta应该是get_user_option。对于单站点,这无关紧要,即使对于多站点,也可能无关紧要。有关原因,请参见wp-admin / includes / ajax-actions.php:update_user_option具有'true'全局参数。

#4 楼

add_filter( 'hidden_meta_boxes', 'custom_hidden_meta_boxes' );
function custom_hidden_meta_boxes( $hidden ) {
    $hidden[] = 'your_metabox';
    return $hidden;
}
还有一个hidden_meta_boxes过滤器,它将在每次页面加载时“取消选中”元框(使其隐藏)(但根本不必更新数据库)。如果您只是想让新用户在自己选中该框之前将其关闭,请使用Rarst的答案。