WordPressで投稿ごとにテンプレートを変える

2016/12/6にWordPress4.7『Vaughan(ヴォーン)』がリリースされましたが、このリリースから投稿タイプ[1]WordPressでは、投稿種別を識別するタイプという識別子データを内部に保持しています。post、page、attachmentなどそれぞれ投稿種別毎に識別子が割り当てられています。
http://wpdocs.osdn.jp/投稿タイプ
が「投稿」についても「ページ」と同様にテンプレートを選択することができるようになりました。以前はプラグインを使ってテンプレートを切り替えていたと思いますが、4.7からはWordPress本体だけでそれが可能になったみたいですので早速試してみたいと思います。

テンプレートの仕組みのおさらい

今までは、投稿タイプが「ページ」のものについては、テンプレートのコメントヘッダに以下のように記述することでWordPressがテンプレートとして認識してくれました。

<?php
/*
Template Name: ここにテンプレート名
*/
?>
Content

WordPressの内部ではテーマディレクトリ下のファイルをスキャンして、ファイル内にTemplate Nameという文字列が存在する場合にテンプレート名として取得するようになっています(wp-includes/class-wp-theme.php)。ここで取得されたテンプレート名は、管理画面内で『ページの編集画面>右サイドの「固定ページの属性」』で選択できるようになります。

ちなみに余談ですが、以下の場合はどうなるか?

テンプレートがサブディレクトリにある場合は?

サブディレクトリにphpファイルがあっても問題ありません。ただし、ディレクトリ階層が2階層以上の場合は認識されません。以下の例で言うと、page_template_sub1.phpまではOKですが、page_template_sub2.phpは認識されません。これは、1階層までをスキャンするようになっているためです。

themes
 |- テーマディレクトリ
   |- page_template_sub_dir_1
     |- page_manual_sub1.php  (OK)
     |- page_template_sub_dir_2
       |- page_manual_sub2.php (認識されない)
   |- page_manual.php  (OK)

Template Nameは先頭でないと駄目か?

Template Nameは、必ずしもファイル先頭でなくても大丈夫ですが、何かと悩まないためにも先頭の方が良いです。正規表現で該当文字列を探索していますが、そこまで厳密ではありませんので以下のような例もOKになります。

何かコンテンツ
何かコンテンツ
何かコンテンツ
<?php
// Template Name: テンプレート名
?>
何かコンテンツ
何かコンテンツ
何かコンテンツ
    <?php Template Name: テンプレート名  ?>
<script>
// Template Name: テンプレート名
</script>
<h3>Template Name: テンプレート名</h3>

HTMLの中でもOK

ただし、こんな場合は思わず悩まされてしまうかもしれないので注意が必要です。

<h3>Template Name: テンプレート名</h3>


<?php
/*
Template Name: こっちが使われない
*/
?>

ファイル内の最初のマッチ情報を使うので、本来使って欲しい「こっちが使われない」のテンプレートが使われません。ということで、テンプレートファイルはテンプレート名でトラブルにならないよう見通し良く作成するのがよいと思います。

新しくなったテンプレート

今までは投稿タイプが「page」に対して可能でしたが、様々な投稿タイプに対してテンプレートを指定することができるようになりました。具体的には、以下のような指定の仕方になります。Template Post Typeという新しいプロパティを指定することができ、投稿タイプをカンマ区切りで指定する形になります。

<?php
/*
Template Name: PostTemplate
Template Post Type: post, page
*/
?>

投稿タイプが、「post」と「page」で有効なテンプレートです。
Typeは、カンマ「,」で区切る必要があります。

この状態で投稿の編集画面を開くと以下のようにテンプレートを選択できるようになります。

また先の例では、投稿タイプにページ(page)も指定しているので、ページの編集画面でもこのテンプレートを選択できます。

これで、今まで「ページ」でしか適用できなかったテンプレート機能を他の投稿タイプにも使えるようになったので、柔軟なコンテンツ作成が可能になりました。専用のプラグインやスラッグ・カスタムフィールド、埋め込みの文字列等でテンプレートを分岐させなくとも、WordPress本体の機能として利用できるので大変便利になりました。

少し内部の実装を見てみよう

どのように変わったか少し内部を見てみます。対象は、wp-includes/class-wp-theme.phpです。

まず、今までのテンプレートを取得するメソッドのシグネチャが変わっています。

// 従来
public function get_page_templates( $post = null ) { ... }

// 4.7以降
public function get_page_templates( $post = null, $post_type = 'page' ) { ... }

この変更だけ見ても、投稿タイプ「page」以外を使えるように拡張されたことが想像できます。もう少し追ってみますと、get_post_templatesというメソッドが追加されており、基本的な流れは従来のget_page_templatesメソッドと同じですが、以下のような今回の追加実装の一部を確認できます。

  $types = array( 'page' );
    if ( preg_match( '|Template Post Type:(.*)$|mi', file_get_contents( $full_path ), $type ) ) {
        $types = explode( ',', _cleanup_header_comment( $type[1] ) );
    }

デフォルトでは、pageという投稿タイプを使うけれど、Template Post Type指定があればそちらを優先するような処理になっています。そして、複数の投稿タイプを指定する場合は、カンマ区切り「,」となります。

と少し内部まで追って見ましたが、既存のpageのテンプレート機能をベースに拡張し、その他の投稿タイプでもテンプレート機能を使えるようになっていることがわかります。

まとめ

WordPress4.7からは、投稿タイプ「page」以外の投稿タイプでもテンプレート機能が使えるようになり、柔軟なコンテンツ作成が可能になったようです。投稿記事ごとに色々なデザインを使い分けたい方には大変便利な機能だと思いますので、是非試してみてはと思います。

参考リンク

 

 

 

エンジニアのためのWordPress開発入門 (Engineer's Library)
野島 祐慈 菱川 拓郎 杉田 知至 細谷 崇 枢木 くっくる
技術評論社
売り上げランキング: 97,855
いちばんやさしいWordPressの教本第3版 人気講師が教える本格Webサイトの作り方 (「いちばんやさしい教本」)
石川栄和 大串 肇 星野邦敏
インプレス (2017-02-24)
売り上げランキング: 805

脚注   [ + ]

1. WordPressでは、投稿種別を識別するタイプという識別子データを内部に保持しています。post、page、attachmentなどそれぞれ投稿種別毎に識別子が割り当てられています。
http://wpdocs.osdn.jp/投稿タイプ

byebyehaikikyou

日記やIT系関連のネタ、WordPressに関することなど様々な事柄を書き付けた雑記です。ITエンジニア経験があるのでプログラミングに関することなどが多いです。

シェアする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする

Translate »