如何使所有人都能访问草稿帖子?


13

我的Wordpress网站上有几篇未发表的帖子,我试图使用普通的帖子标签(site.com/post-here)使普通用户(未登录)可以访问它。我了解这可能不是最佳做法,但出于我的特殊目的,需要这样做。

我尝试将以下代码段添加到我的functions.php文件中:

function enable_view_drafts() {
$role = get_role( 'subscriber' ); 
$role->add_cap( 'read_private_posts' ); 
$role->add_cap( 'edit_posts' );
}
add_action( 'after_setup_theme', 'enable_view_drafts');

我也尝试使用init钩子代替after_setup_theme。没运气。

我的理解是对角色的更改已保存到数据库中,因此只需执行一次。这就是为什么我使用after_setup_theme钩子来调用函数的原因。

但是,当我尝试以普通用户身份访问页面时,系统显示的是404页面,而不是帖子内容。我也尝试加载预览URL(site.com/?p=212&preview=true),但是也没有用。

这些是我的猜测:

  • 普通用户没有足够的时间caps来阅读草稿帖子。
  • 任何用户(包括管理员)都无法测试和查看前端的草稿。

为了完成我要完成的工作,我必须进行哪些更改?如果不可能,您建议什么替代解决方案?

注意:我不是在寻找基于插件的解决方案。


2
我认为这里有些混乱。如果某人未登录,则他/她不是用户,因此他/她没有任何上限。该用户是用户,所以他们必须要注册并登录到被识别为订阅者。您不能为尚未登录的人员提供功能。如果您希望未登录的任何人查看您的帖子,则与发布的帖子完全没有区别。那么,为什么不发布它呢?还是要向订阅者显示草稿(以订阅者身份登录)?
gmazzap

@GM:我想让所有知道直接固定链接的人都可以访问发布的帖子。看来这是一个奇怪的要求,但是我在项目中需要它。正如我在问题中提到的那样,如果这不可能—您能建议其他解决方法吗(当然,如果知道的话)?
阿马尔·穆拉利

@GM:您知道哪个插件吗?
Amal Murali13年

您是否读过下面的3赞答案?它解释了如何执行此操作,在答案的最后,您找到了一个链接,可从github下载完整的可运行插件。
gmazzap

2
对于以后的读者:Dominik Schilling此插件可在GitHub上获得。
kaiser

Answers:


12

您无法将功能分配给未知用户。如果要使所有人都能看到帖子,请为这些帖子创建一个单独的URL,并将控件元素添加到帖子编辑器中,以仅对选定的帖子启用预览。
调用此类URL时,请检查是否允许发布该帖子的预览,以及该发布是否尚未发布。另外,请确保搜索引擎忽略此URL。

对于URL,我将使用一个端点

add_rewrite_endpoint( 'post-preview', EP_ROOT );

现在,您可以创建类似……的URL。

http://example.com/post-preview/123

123帖子的ID。

然后使用回调处理程序检查帖子ID,检查其是否有效并覆盖主查询。这可能是唯一可接受的用例query_posts()。:)

假设端点是一个类T5_Endpoint(一个模型),而输出处理程序是一个类T5_Render_Endpoint(一个视图),它使模型较早通过。然后可能有一个方法render()被调用template_redirect

public function render()
{
    $post_id = $this->endpoint->get_value();

    if ( ! $post_id )
        return;

    if ( 1 !== $this->meta->get_value( $post_id )
        or 'publish' === get_post_status( $post_id )
        )
    {
        wp_redirect( get_permalink( $post_id ) );
        exit;
    }

    $query = array (
        'suppress_filters' => TRUE,
        'p'                => $post_id,
        'post_type'        => 'any'
    );

    query_posts( $query );

    add_action( 'wp_head', 'wp_no_robots' );
}

$this->metaT5_Post_Meta用于发布元值的另一个模型(类),用于控制是否允许预览。控件设置在Publish框(actionpost_submitbox_misc_actions)中,由另一个获得相同元类的视图呈现。

屏幕截图

因此,T5_Post_Meta知道了在何处以及何时存储元值时,视图就会对其进行处理。
同样,发布发布时,请钩入transition_post_status以删除发布元字段。我们不想浪费资源,对吗?

这只是一个大纲。有很多细节需要介绍……我已经写了一个小插件来演示如何实现:T5 Public Preview


非常感谢。我终于通过一些调整实现了我的目标。太棒了 :D
Amal Murali

6

我以比@toscho上面的答案更简单的方式解决了这个问题。

我的用例是我为内部Intranet登台站点和面向公众的站点使用相同的数据库,工作流程是作者编写草稿并与其他用户共享,然后再在发布之前在Intranet站点上查看这些草稿的其他用户共享。我特别不想让审阅者登录以查看草稿,因此我仅依赖于一个常量,ENV_PRODUCTION该常量是根据中的主机名在wp-config文件中设置的$_SERVER['SERVER_NAME']。这就是检查的ENV_PRODUCTION结果。如果正在查看生产现场,则只需短路所有这些过滤器即可。

这有点奇怪,因为在WP_Query从$ wp_query-> posts数组中删除所有帖子之后,您必须上钩,但是对我来说,它似乎稳定且安全。

/*
 * On staging site home and archives, drafts should be visible.
 */
function show_drafts_in_staging_archives( $query ) {
    if ( ENV_PRODUCTION )
        return;

    if ( is_admin() || is_feed() )
        return;

    $query->set( 'post_status', array( 'publish', 'draft' ) );
}

add_action( 'pre_get_posts', 'show_drafts_in_staging_archives' );


/*
 * Make drafts visible on staging site single views.
 *
 * (Because on single views, WP_Query goes through logic to make sure the 
 * current user can edit the post before displaying a draft.)
 */
function show_single_drafts_on_staging( $posts, $wp_query ) {
    if ( ENV_PRODUCTION )
        return $posts;

    //making sure the post is a preview to avoid showing published private posts
    if ( ! is_preview() )        
        return $posts;

    if ( count( $posts ) )
        return $posts;

    if ( !empty( $wp_query->query['p'] ) ) {
        return array ( get_post( $wp_query->query['p'] ) );
    }
}

add_filter( 'the_posts', 'show_single_drafts_on_staging', 10, 2 );

过滤器有两个单独的部分。

  • 在登台站点上,“ pre_get_posts”挂钩上的过滤器将默认post_status设置为“发布,草稿”。这将把帖子草稿返回到存档列表中。
  • 单个视图需要一个单独的过滤器,因为WP_Query类中存在一些讨厌的逻辑,可从查询结果中删除草稿,除非当前的用户可以对其进行编辑。我通过过滤'the_posts'来解决这个问题,然后将我想要的帖子添加回结果中。

2
真是不可思议非常感谢您分享。绝对完美,正是我所需要的。
Christian Varga,2015年

该代码放在哪里?(哪些文件?)
Joelio

@Joelio您能具体说明您要解决的问题吗?作为一种简单的方法,我只是将此代码添加到我的functions.php中,并向我的wp-config.php中添加了一个简单的定义,该定义将ENV_PRODUCTION常量根据请求域设置为true或false。
goldenapples

@goldenapples我将这段代码添加到我的function.php中,我应该在wp-config中添加什么?感谢您的帮助
Graham Slick 2015年

@MatthiasGrahamSlick-您只需要一些ENV_PRODUCTION可以在生产中设置常量的东西。我当时使用domain.com进行生产,使用staging.domain.com进行过渡,所以我的台词是define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );“那有帮助吗?
goldenapples

0

我认为WordPress.org网站上提供的“用户角色编辑器”插件可能正是您所需要的。顺便说一句,为什么要让所有人都可以使用草稿?我个人想不出需要这样做的实例。


不,正如问题中提到的那样,我不是在寻找基于插件的解决方案。用例有些复杂,但是我确信这是我要完成的特定任务的最佳解决方案。:-)
Amal Murali 2013年

我也对原因感到困惑。如果您希望每个人都看到该帖子,为什么不简单地发布该帖子呢?您可以在帖子上使用自定义字段来跟踪您可能希望定义的任何特殊状态。
KenB

我让用户看到内容,但是出于某些特定原因,我不希望发布这些帖子。
Amal Murali13年

0

您可以将页面/帖子上的可见性更改为“私人”,只有编辑者和管理员才能看到,而公共访问者,搜索引擎,rss提要等则不可见。


0

我认为通用汽车的评论是这里最好的。我认为您正在尝试执行以下操作:

  1. 写一个帖子
  2. 保存为草稿
  3. 允许外部(未登录)用户查看草稿以供批准
  4. 发布

那是对的吗?

不幸的是,我想不出任何简单的方法来做到这一点。您可以将其发布为私人帖子,以便他们需要输入密码才能查看它,但您需要为此登录。您也可以用密码保护它,但是它仍然会出现在您的供稿和最近的帖子列表等中。当您给他们提供URL时,您是否无法创建访客用户帐户并为他们提供用户名/密码?

在这里阅读更多信息:http : //codex.wordpress.org/Content_Visibility

另外,有一个可能满足您需求的插件:http : //wordpress.org/extend/plugins/shareadraft/ 我快速浏览了一下代码,看来开发人员正在修改get_post_status返回的值,因此您可能会能够解决这个问题:

http://codex.wordpress.org/Function_Reference/get_post_status

高温超导


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.