WordPressのパスワード保護で、パスワード未入力でも見える範囲を任意に決められるようにする

本稿では、Wordpressのパスワード保護機能の利用時に、パスワード未入力でも一部コンテントを表示したり、また入力時とは別のコンテントを表示したりする方法を示します。

またその利用例として、画像ギャラリーにてパスワード入力時のメンバー表示と、未入力時の一般公開を分ける方法についても示します。

ここでのパスワード保護とは、編集画面の公開パネルにて、公開状態に「パスワード保護」を選択した状態を指します。

はじめに

ひさしぶりにWordpressの話題です。

既に出来上がっているサイトでパスワード保護を使っているのですが、ページ内のコンテンツの一部は、パスワードを入力していない状態でも見えるようにしたくなりました。

パスワードを入力した状態と入力していない状態とで表示を変えたい、とも言いかえることができます。

検索してみると、パスワード保護の時に、本文ほかタイトルなどを見えなくするという厳しい方向の方法はヒットします。逆の、緩くする方向の方法はみつかりませんでした。

正攻法ではありませんが、Google先生が教えてくれる情報の範囲内で実現できました。

注意書き

本稿での方法は、パスワード保護機能を活用して出来上がっているサイトにおいて、後から一部分を一般公開したくなったときの事例です。

もし新規作成するサイトの中で同様なことをやりたい場合は、適切なプラグインを探したほうがよいかもしれません。

またこの方法ではパスワードの入力フォームがページタイトルの下に表示されます。

タイトルの上にフォームを表示したい場合にも使えません。

尚、動作確認はWordPress4.9.5です。

作戦

作戦は以下です。

  • パスワード未入力時に表示したい内容も本文に書けるようにする。ショートコードで囲って書き分ける。
  • パスワードフォームをカスタマイズする方法のフックの中で、パスワード未入力時用のコンテントを取得し、フォームの下に付けて出力する。

本来はパスワードフォームのフックより上位のフックで引っかけて、そこで条件分岐するのが正攻法なのでしょう。

しかし調べるのも面倒だし、わざわざWordpressさんが条件分岐してパスワードフォームのフックを呼んでくれているので、これで良しとしました。

また1点目について、カスタムフィールドを使う手も考えられますが、書く時にコピペが必要だし入力ボックスが狭いしなので、本文に書けるようにしました。

実装

コードはすべて「wp-content/themes/<使用中のテーマ>/functions.php」に追加します。

パスワード入力フォームを改造する

この方法は結構検索にヒットします。

それらを参考に、フォームの後にパスワード未入力時のプレビューも出力するようにします。

//	パスワードフォーム
function org_password_form() {
	global $post;
	$preview = '';
	if(preg_match('/\[passwd_preview([^\]]*)\]/',$post->post_content)) {
		$preview = apply_filters('the_content', $post->post_content);
	}
	$message = 'このページを閲覧するには、パスワードの入力が必要です。';
	if(!empty($preview)) {
		$message = '※只今一般公開可能な内容のみを表示しています。'
		.'すべてを表示するには、パスワードの入力が必要です。';
		$preview = '<hr/><div class="passwd_preview">'.$preview.'</div>';
	} else if ( has_excerpt() ) {
		$preview = '<hr/><div class="passwd_preview">'.$post->post_excerpt.'</div>';
	}
	$form = '<form class="passwd_form" action="'
		.home_url().'/wp-login.php?action=postpass" method="post">'
		.'<p>'.$message.'</p>'
		.'<p><input name="post_password" type="password" />&nbsp;'
		.'<input type="submit" value="'.esc_attr__("送信").'" /></p>'
		.'</form>';
	return $form . $preview;
}
add_filter('the_password_form', 'org_password_form'); 

フォームのHTMLを生成する関数を作って、それを最後の行のadd_filterにてthe_password_formフックに登録してあげるというのが、所謂フォームを改造する方法です。

関数org_password_formの後半はほぼこの方法ですが、$previewにパスワード未入力時のコンテントを作ってあげて、最後のreturnのようにフォームの後ろにくっつけて返します。

5-7行がそのプレビュー用のコンテント取得です。[passwd_preview]というショートコードが本文内にある場合のみ、ショートコードなどを適応した本文を$previewにセットします。

もしかしたらショートコードでない[passwd_preview]という文字列が引っ掛かる場合もあるかもしれませんが、この記事のような場合以外はないでしょうから、これでよしとしました。

8行は、表示するプレビューがない場合のメッセージです。プレビューがある場合は10-12行にて適切なメッセージとHTMLに整形します。

13,14行では、プレビューがない場合でも抜粋が書かれていれば、それを整形して出力するようにしています。has_excerptは抜粋があるときにはtrueが返る関数です。

パスワード保護状態では抜粋も出力しないのがWordpressのデフォルトの仕様ですから、もし必要なければこれらの行はなくてもかまいません。

以上で、パスワード未入力時のプレビュー出力ができました。

ショートコード

続いて、パスワード入力時と未入力時を分けて記述できるショートコードを書きます。

仕様としては、[passwd_preview authorized=true][/passwd_preview]の中にパスワード入力時(或はパスワード保護なしの時)のコンテントを書き、[passwd_preview authorized=false][/passwd_preview]の中にパスワード未入力時のコンテントを書くことを想定しています。

//	パスワード保護のコンテンツの、プレビューショートコード
function shortcode_passwd_preview( $atts, $content='' ) {
	$atts = shortcode_atts(
		array(
			'authorized' => false,
		), $atts, 'passwd_preview' );
	$authorized = $atts['authorized'];
	$authorized = (empty($authorized) || trim($authorized)==='false')? false: true;
	global $post;
	if(post_password_required($post)) {
		if(!$authorized) return do_shortcode($content);
	} else {
		if($authorized) return do_shortcode($content);
	}
	return '';
}
add_shortcode( 'passwd_preview', 'shortcode_passwd_preview' ); 

3-8行までで、変数$authorizedに属性authorizedの設定値がbooleanで格納されます。’false’以外のときはtrueとアバウトですが。

10行のpost_password_requiredという関数は、パスワード保護がなされており、且つパスワード未入力の場合にtrueが返る関数です。このとき、authorizedがfalseならショートコードの中身を処理して返します。

保護されていないか入力済の場合は、13行にてauthorizedがtrueなら返します。

それ以外の場合は空の文字列を返します。

本文の書き方

投稿の本文には、以下のように書きます。

すべての場合に表示される文章
[passwd_preview authorized=true]
パスワード入力時のみ表示される文章
[/passwd_preview]
[passwd_preview authorized=false]
パスワード未入力時のみ表示される文章
[/passwd_preview]

そして[passwd_preview]のショートコードがない場合は、パスワード未入力時にはなにも表示されません。

パスワード未入力のテストする時は、クッキーを削除しないといけないので面倒です。違うブラウザを使うのが楽ですね。

追加のコード

先のコードでは、パスワード保護時で本文にプレビューがないときでも、そのかわりに抜粋をフォームの下に表示するようにしました。そこでそのほかの場所でも抜粋は見られるようにします。またタイトルの「保護中」も変えます。

これらの方法も検索にてよく見つかります。

//	パスワード保護でも抜粋を有効にする。
function enable_excerpt_of_protected( $output ) {
	global $post;
	global $wpmp;
	if ( post_password_required( $post ) ) {
		if( has_excerpt() ) {
			$output = $post->post_excerpt;
		} else {
			$output = $wpmp->trim_multibyte_excerpt($post->post_content);
		}
	}
	return $output;
}
add_filter( 'the_excerpt', 'enable_excerpt_of_protected', 0 );

//	パスワード保護の時のタイトル
function org_protected_title($title) {
       return '%s (PW付)';
}
add_filter('protected_title_format', 'org_protected_title'); 

最初の関数でパスワード保護(post_password_requiredの戻りがtrue)の場合に抜粋を作っています。抜粋がない場合にWP multibyte patchのメソッドを直接呼んでpost_contentから抜粋を作っていますが、もしかしたら適切なフィルターフックがあるのかもしれません。

2つめの関数で、パスワード保護中のタイトルが「<タイトル> (PW付)」となるようにしています。何もつけたくない場合は、「return ‘%s’;」とします。

 

以上で目的は達成しました。

画像ギャラリーを切り替える

活用例としては、画像のギャラリーがあります。

ギャラリーの中に顔写真などがあり、これらはパスワードで保護してメンバーのみ公開としたい、しかし風景などは一般公開したい、というような場合に使えます。

私が使っているのは「NextGEN Gallery」というプラグインです。

その使い方はどなたかが既に書いているのでここで書くことはしませんが、上記で作ったショートコードとの併用について書きたいと思います。

編集画面にてNextGEN Galleryの緑の■をクリックすると、設定を経てギャラリーが挿入されます。最初のギャラリーはパスワード入力時に表示する完全なものだとして、[passwd_preview authorized=true][/passwd_preview]のショートコードで囲みます。

 

その後にもう一つ、同様なギャラリーをつくります。こちらはパスワード未入力でも一般公開するギャラリーです。

緑の■をクリックし、ギャラリーの設定画面では先と同じ様に再び設定します。

それが終わったら、一番下の「Sort or Exclude Images」をクリックし、画像を見ながら一般公開はしたくない画像の下の「Exclude?」にチェックしていきます。

終わってSaveしたら、そのギャラリーを[passwd_preview authorized=false][/passwd_preview]のショートコードで囲みます。

空行が気になるようであれば、テキストモードで調整します。

おわりに

以上パスワード保護時に、一部を表示させたり表示を別けたりする方法でした。

私の要求は満足しましたが、あくまでも正攻法とは思っていませんので、より完璧を期する方は上位のフックをあたってみてください。

コメントを残す