除非登录,否则隐藏特定类别的帖子

时间:2015-12-28 作者:Henrik

我想隐藏属于某个类别的帖子,除非登录。

我在抄本中找到了一些代码(附件),这些代码对循环非常有用。但是如何确保帖子页面也是空的呢?

function exclude_category($query) {
  if (!is_user_logged_in()) {
    $query->set(\'cat\', \'-2\');
  }
}
add_action(\'pre_get_posts\', \'exclude_category\');

1 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

我只需将该特定类别的所有帖子的帖子状态设置为private. 如果您已经有大量帖子,请使用wp_update_post() 将所有这些帖子的帖子状态更新为private. 在此之后发布的任何帖子都可以设置为private (“发布元”框中的)。

默认情况下,主查询仅显示登录用户的私人帖子

从评论中编辑(EDIT from COMMENTS)

评论中的OP添加内容,将来可能会有用

这很好,只是它要求用户有太多的权力(作为编辑)来阅读私人帖子。我通过在插件中添加以下内容来解决此问题:$subRole = get_role( \'subscriber\' ); $subRole->add_cap( \'read_private_pages\' ); $subRole->add_cap( \'read_private_posts\' );

第二次加法$posts 到所有类别页的空数组,其中4 是类别,如果文章属于类别4,则也可以在任何单个页面上显示

add_filter( \'the_posts\', function ( $posts, $q )
{
    if ( is_user_logged_in() )
        return $posts;

    if (    $q->is_main_query()
         && (    $q->is_category( 4 )
              || (    $q->is_single() 
                   && has_category( 4, $posts[0] )
                 )
             )
    ) {
        return $posts = [];
    }
    return $posts;
}, 10, 2 );
这应该不会在循环中返回POST。这都是未经测试的,所以在生产现场使用之前需要进行适当的离线测试

请注意,如果一篇文章属于类别4的后代,并且该文章没有明确分配给类别4,则此操作将失败。这也适用于类别4的后代类别页面。要实现这一点,您需要添加额外的检查来检查类别的顶级父级,但这可能会导致很大的运行开销

最终版

以上过滤代码现在已经过测试,并且正在处理单页和类别页上的主要查询。在分类页面上,循环显示没有帖子,在单个页面上,它确实会导致404页。您可以使用pre_get_posts 删除属于第2类的任何其他职位

add_action( \'pre_get_posts\', function ( $q )
{
    if ( is_user_logged_in() )
        return;

    if (    !is_admin() // Target only front end
         && !$q->is_singular() // Do not target singular pages
         && $q->is_main_query() // Target only the main query
    ) {
        $q->set( \'cat\', -4 );
    }
});
设计中的缺陷尽管代码可以正常工作,但它确实存在漏洞,比如自定义查询和用于从类别中列出帖子的页面。这是一条危险的路线,私人信息可能会无意中显示给未登录的用户(例如,通过错误的自定义查询)

结论解决这个问题最安全的方法是将帖子设置为私有,只应向登录用户显示。正如您已经显示的那样(在评论中),一旦登录,就可以很容易地调整角色以向他们显示私人帖子

相关推荐

为内置钩子调用do_action和Apply_Filters是否安全?

我正在开发一个插件,它需要复制一些内置的WordPress逻辑。(此逻辑不能用任何内置方法调用,也不能独立连接到。)在这个动作序列中,WordPress的正常行为是调用动作挂钩(do_action(\'wp_login\', ...)) 和过滤器挂钩(apply_filters(\'login_redirect\', ...)).如果在对应于在Core中调用它们的时间点调用它们,那么直接从我的插件调用这些内置钩子是否安全(并且是可以接受的做法)?或者,其他与此相关的开发人员期望在非常特定的时间执行操作的风