web-dev-qa-db-ja.com

ドラフト投稿を全員が閲覧できるようにするにはどうすればよいですか。

私は私の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');

私はafter_setup_themeの代わりにinitフックを試しました。運がありません。

私の理解するところでは、ロールへの変更はデータベースに保存されるので、一度だけ行えばよいということです。これが私がafter_setup_themeフックを使って関数を呼び出す理由です。

しかし、私が普通のユーザーとしてページにアクセスしようとすると、投稿内容を表示する代わりに404ページが表示されます。プレビューURL(site.com/?p=212&preview=true)もロードしようとしましたが、うまくいきませんでした。

これらは私の推測です:

  • 一般ユーザは下書き投稿を読むのに十分なcapsを持っていません。
  • フロントエンドでドラフト投稿をテストして表示することは、どのユーザー(管理者を含む)でも不可能です。

自分がやろうとしていることを達成するために、どのような変更を加える必要がありますか?それが不可能な場合は、他にどのような解決策を提案しますか?

注: 私はプラグインベースのソリューションを探していません。

12
Amal Murali

未知のユーザーに機能を割り当てることはできません。誰もが投稿を表示できるようにするには、これらの投稿に個別のURLを作成し、投稿エディタにコントロール要素を追加して、選択した投稿のプレビューのみを有効にします。
このようなURLが呼び出されたときに、投稿のプレビューが許可されているかどうか、および投稿がまだ公開されていないかどうかを確認してください。また、検索エンジンがこのURLを無視するようにしてください。

URLには endpoint を使います。

add_rewrite_endpoint( 'post-preview', EP_ROOT );

今、あなたはのようなURLを作成することができます…

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

123は投稿IDです。

その後、コールバックハンドラを使用して投稿IDを調べ、それが有効であるかどうかを確認してメインクエリを上書きします。おそらくこれがquery_posts()の唯一の許容できるユースケースです。 :)

エンドポイントはクラスT5_Endpoint(モデル)であり、出力ハンドラはモデルを先に渡すクラスT5_Render_Endpoint(ビュー)です。それからおそらくtemplate_redirectで呼ばれるメソッドrender()があります:

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->metaは、プレビューが許可されるかどうかを制御するpostメタ値のための別のモデル(クラスT5_Post_Meta)です。コントロールは Publish ボックス( action post_submitbox_misc_actions )に設定され、同じメタクラスを取得する別のビューによってレンダリングされます。

screen shot

そのためT5_Post_Metaはメタ値をどこにいつ格納するかを知っていて、ビューはそれを使って何かをします。
また、投稿が公開されたときに投稿メタフィールドを削除するには、 transition_post_status にフックします。私たちは資源を無駄にしたくありませんね。

これは単なる概要です。カバーするべき多くの詳細があります…私はこれをどのように実装するかを示す小さなプラグインを書きました: T5公開プレビュー

12
fuxia

私は上記の@ toschoの答えよりも簡単な方法だと思ったことでこの問題を解決しました。

私のユースケースは、社内イントラネットステージングサイトと一般向けサイトで同じデータベースを使用していることです。ワークフローは、作成前に作成者がドラフトを作成し、イントラネットサイトでドラフトを閲覧する他のユーザーと共有することです。ドラフトを見るためにレビューアにログインを要求したくなかったので、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 );

フィルタには2つの部分があります。

  • "pre_get_posts"フックのフィルタはステージングサイトのデフォルトのpost_statusを 'publish、draft'に設定します。これはアーカイブリストのドラフト投稿を返します。
  • WP_Queryクラスには、現在の管理者が編集できない限り、ドラフト投稿をクエリ結果から削除するための厄介なロジックがいくつかあるため、単一のビューには個別のフィルタが必要です。この問題を回避するには、「the_posts」をフィルタリングし、必要な投稿を追加して結果に戻します。
5
goldenapples

私はWordPress.orgのウェブサイトで入手可能な「User Role Editor」プラグインがあなたが探しているものであるかもしれないと思います。ところで、なぜあなたはドラフトへのアクセスを誰にでも与えたいのですか?私は個人的にこれが必要とされるインスタンスを考えることはできません。

0
Georgi Demirev

投稿が「公開」されているかどうか気にしない場合は、通常の公開URLで誰でもアクセスでき、メインページ/検索結果/ rssフィードなどには表示されないように、このプラグインはWP 4.6.1で、投稿が表示される場所を微調整できます。

https://wordpress.org/plugins/wp-hide-post/

0
Sarah Northway

ここではG.M.のコメントが最高だと思います。私はあなたが次のことをしようとしていると仮定します:

  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

HTH

0
TomC

ページ/投稿の表示を編集者と管理者にのみ表示され、一般の訪問者、検索エンジン、RSSフィードなどには表示されない「非公開」に変更することができます。

0
NickJAB