誰でもドラフト投稿にアクセスできるようにするにはどうすればよいですか?


13

Wordpress Webサイトに未公開の投稿がいくつかあり、通常の投稿スラッグ(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:それを行うプラグインを知っていますか?
アマルムラリ

以下の回答を3回の投票で読んだことがありますか?それを行う方法を説明し、答えの最後にgithubから完全に機能するプラグインをダウンロードするためのリンクを見つけます。
gmazzap

2
後の読者向け:Dominik Schillingによるこのプラグインが GitHubで利用可能です。
カイザー

回答:


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()on というメソッドがあります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プレビューを許可するかどうかを制御するポストメタ値の別のモデル(クラス)です。コントロールは、同じメタクラスを取得する別のビューによってレンダリングされる[ 発行]ボックス(actionpost_submitbox_misc_actions)に設定されます。

スクリーンショット

したがってT5_Post_Meta、メタ値をどこにいつ保存するかを知っているので、ビューはそれを使って何かをします。
また、投稿が公開されたときに投稿メタフィールドを削除するためにフックしtransition_post_statusます。リソースを無駄にしたくありませんか?

これは単なる概要です。カバーする多くの詳細があります...私はこれを実装する方法を示す小さなプラグインを書きました:T5 Public Preview


どうもありがとうございます。私は最終的にいくつかの調整で目標を達成しました。驚くばかり。:D
アマルムラリ

6

上記の@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」をフィルタリングし、目的の投稿を結果に追加し直しました。

2
これはすごいです、これを共有してくれてありがとう。絶対に完璧で、まさに必要なもの。
クリスチャンヴァルガ

このコードはどこに置きますか?(どのファイルですか?)
Joelio

@Joelio解決しようとしている問題について具体的に説明していただけますか?簡単なアプローチとして、このコードをfunctions.phpに追加し、リクエストドメインに応じてENV_PRODUCTION定数をtrueまたはfalseに設定するwp-config.phpに簡単な定義を追加しました。
goldenapples

@goldenapplesこのコードをfunction.phpに追加しましたが、wp-configに何を追加すればよいですか?ご協力ありがとうございます
グラハムスリック

@MatthiasGrahamSlick-本番環境のENV_PRODUCTION場合に定数を設定するものが必要です。私は本番用にdomain.comを使用し、ステージング用にstaging.domain.comを使用define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );していました。
ゴールデンアップル

0

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


いいえ、質問で述べたように、プラグインベースのソリューションを探していません。ユースケースは少し複雑ですが、これが私が達成しようとしているこの特定のタスクに最適なソリューションであると確信しています。:-)
アマルムラリ

私もその理由に戸惑っています。誰もが投稿を閲覧できるようにする場合は、投稿を単純に公開してみませんか?投稿のカスタムフィールドを使用して、定義したい特別な状態を追跡できます。
KenB

ユーザーにコンテンツを見せることはできますが、特定の理由により、投稿を公開したくありません。
アマルムラーリ

0

ページ/投稿の可視性を「プライベート」に変更するだけで、編集者と管理者にのみ表示され、一般の訪問者、検索エンジン、RSSフィードなどには表示されません。


0

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

  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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.