2026年7月21日

2026年7月21日

WordPressのカスタムページテンプレートを投稿者のロールで切り替える方法

記事を書いたユーザーのロール(権限グループ)によって表示テンプレートを変えたい場合は、page_template_hierarchy や single_template_hierarchy といったテンプレート階層のフィルターで、候補の先頭に専用テンプレートを追加するのが扱いやすい方法です。この方法ならクラシックテーマでもブロックテーマでも同じ考え方で動き、編集画面で手動選択したテンプレートも尊重できます。この記事では、作成者のロールを取得する方法、テンプレートファイルの用意、切り替えのコード、閲覧者のロールで切り替える場合の注意点、確認方法までを説明します。

最初に確認したい前提

WordPress の標準ロールは、管理者(administrator)、編集者(editor)、投稿者(author)、寄稿者(contributor)、購読者(subscriber)の5種類です。コードの中ではカッコ内の英語のスラッグで判定します。

ここで注意したいのは、標準の設定では「投稿者」ロールは固定ページを作成・編集できないことです。投稿者が持っているのは投稿(post)に関する権限で、固定ページの編集権限は編集者以上にしかありません。そのため「投稿者が書いたページだけテンプレートを変える」という要件は、実際には次のどちらかであることが多いです。

  • 投稿(post)の個別表示を、作成者のロールで切り替えたい
  • ロールの権限を独自に変更していて、投稿者や独自ロールも固定ページを作れる

この記事のコードは、固定ページと投稿の両方に対応させています。なお WordPress 4.7 以降は、テンプレートファイルの先頭に Template Post Type: を書けば、カスタムページテンプレートを投稿にも適用できます。

作業はテーマの更新で消えないように、子テーマで行います。サイトのバックアップを取り、ステージング環境で表示を確かめてから本番に反映してください。

テンプレートが選ばれる仕組み

WordPress は表示するページの種類に応じて、テンプレートの候補を並べた配列を作り、先頭から順に存在するファイルを探します。固定ページなら、編集画面で選んだテンプレート、page-{スラッグ}.php、page-{ID}.php、page.php の順です。投稿なら、選んだテンプレート、single-post-{スラッグ}.php、single-post.php、single.php の順になります。

この候補の配列は、{種類}_template_hierarchy という名前のフィルターで変更できます。固定ページは page_template_hierarchy、投稿などの個別表示は single_template_hierarchy です。ここで候補の先頭に専用テンプレートを入れれば、そのファイルがあるときだけ優先して使われ、無いときは通常の候補にフォールバックします。

ブロックテーマでも、同じ候補の配列から .php を除いた名前で templates/ フォルダー内の HTML テンプレートが探されます。そのため同じフィルターが使えます。

専用テンプレートを用意する

クラシックテーマなら、子テーマの直下に専用テンプレートを置きます。ここでは寄稿者と投稿者のための2種類を例にします。

wp-content/themes/mytheme-child/
├── page-role-contributor.php
├── single-role-author.php
└── single-role-contributor.php

中身は、親テーマの page.php や single.php をコピーして、表示を変えたい部分だけを書き換えると作りやすくなります。たとえば寄稿者の記事には「ゲスト寄稿」の帯を出す、編集部の記事とは著者欄の見せ方を変える、といった使い方です。

ブロックテーマの場合は、子テーマの templates/ フォルダーに single-role-author.html などを置きます。サイトエディター側でテンプレートを編集した場合はデータベースに保存されるので、ファイルとの違いに注意してください。

これらのファイルには Template Name: の見出しを書いていません。見出しを書くと編集画面のテンプレート選択に表示されますが、今回はロールで自動的に選ぶものなので、選択肢に出さない方が編集者を迷わせません。

作成者のロールで切り替えるコード

子テーマの functions.php に次のコードを追加します。

/**
 * 作成者のロールに応じて、テンプレート候補の先頭に専用テンプレートを追加する。
 */
function mytheme_role_template_candidates( $templates ) {
	$post = get_queried_object();
	if ( ! $post instanceof WP_Post ) {
		return $templates;
	}

	// 編集画面でテンプレートが手動選択されていれば、それを優先する
	if ( get_page_template_slug( $post ) ) {
		return $templates;
	}

	$author = get_userdata( (int) $post->post_author );
	if ( ! $author ) {
		return $templates;
	}

	$prefix = ( 'page' === $post->post_type ) ? 'page' : 'single';

	// 上にあるロールほど優先する
	$roles = array( 'contributor', 'author' );

	foreach ( $roles as $role ) {
		if ( in_array( $role, (array) $author->roles, true ) ) {
			array_unshift( $templates, $prefix . '-role-' . $role . '.php' );
			break;
		}
	}

	return $templates;
}
add_filter( 'page_template_hierarchy', 'mytheme_role_template_candidates' );
add_filter( 'single_template_hierarchy', 'mytheme_role_template_candidates' );

get_userdata() で作成者のユーザー情報を取得し、その roles プロパティ(配列)に目的のロールが含まれているかを in_array() で厳密に比較しています。1人のユーザーが複数のロールを持つこともあるため、優先するロールの順番を配列で決めておくと、結果が予測しやすくなります。

get_page_template_slug() で手動選択の有無を確認しているのは、編集者が意図して選んだテンプレートを自動処理で上書きしないためです。逆に、ロールによる切り替えを常に優先したい場合は、この判定を外します。

候補に追加したファイルが存在しない場合は、WordPress が次の候補を探すので、表示が真っ白になることはありません。テンプレートを1つずつ用意して、段階的に試せます。

ロールより権限で判定する方がよい場合

ロール名で判定すると、ロール管理プラグインで独自ロールを作ったときや、ロール名を変えたときに条件から漏れます。「記事を公開できない人の記事」を見分けたいなら、ロールではなく権限で判定する方が意図に合います。

// 作成者が他人の記事を編集できない(編集部ではない)なら、ゲスト用テンプレートにする
if ( ! user_can( $author, 'edit_others_posts' ) ) {
	array_unshift( $templates, $prefix . '-role-guest.php' );
}

user_can() は、指定したユーザーが特定の権限を持つかを判定する関数です。権限の名前(edit_others_posts など)は WordPress コアで定義されたものを使います。

閲覧者のロールで切り替える場合の注意

「記事を書いた人」ではなく「今見ている人」のロールで切り替えたい場合は、wp_get_current_user() で現在のユーザーを取得して同じように判定できます。ただし、次の2点に注意が必要です。

1つ目はページキャッシュです。キャッシュプラグインやサーバーのキャッシュが有効だと、最初に表示した人のテンプレートが保存され、他の人にもそのまま配信されることがあります。多くのキャッシュはログイン中のユーザーを対象外にしますが、設定によって異なるため、ログイン状態を変えて実際の表示を確かめてください。

2つ目は、テンプレートの切り替えはアクセス制限ではないことです。会員だけに見せたい内容を「会員用テンプレートにだけ書く」形にしても、本文や REST API、フィードなど別の経路から内容が見えることがあります。閲覧の可否を制御したい場合は、current_user_can() による判定を本文の出力側に入れるか、会員制サイト向けのプラグインを使ってください。

表示を確認する方法

  • Query Monitor を使う:プラグインの Query Monitor を有効にすると、管理バーの表示から、そのページで使われたテンプレートファイルと候補の一覧を確認できます。候補の先頭に追加したファイル名が出ているかを見れば、フィルターが効いているかが分かります。
  • 作成者を変えて試す:テスト用に寄稿者や投稿者のユーザーを作り、そのユーザーを作成者にした記事を表示します。本番のユーザーの権限を一時的に変えて試すのは避けてください。
  • 切り替わらない場合:テンプレートが手動選択されていないか、ファイル名の接頭辞(page- か single-)が投稿タイプと合っているか、子テーマが有効になっているかを確認します。ブロックテーマでは、サイトエディターでカスタマイズ済みのテンプレートがファイルより優先されることがあります。

テンプレート階層の挙動やブロックテーマでのテンプレートの探し方は、バージョンアップで細かく変わることがあります(2026年10月現在)。大きな更新の後は、上の確認をもう一度行うと安心です。

まとめ

  • テンプレートの切り替えは、page_template_hierarchy と single_template_hierarchy で候補の先頭に専用テンプレートを追加すると、クラシックテーマとブロックテーマの両方で扱いやすい
  • 作成者のロールは get_userdata() の roles で取得し、in_array() で厳密に比較する。独自ロールが絡むなら user_can() で権限を判定する
  • 標準の「投稿者」は固定ページを作れないため、投稿の個別表示も対象に含めて設計する
  • 手動選択されたテンプレートは get_page_template_slug() で判定して尊重する
  • 閲覧者のロールで切り替える場合はページキャッシュに注意し、テンプレート切り替えをアクセス制限の代わりにしない

お気軽にご相談ください

お見積りへ お問い合わせへ
▲