【初級・中級】wordpressのテンプレートタグをTwenty Nineteenを見ながら解説する

wordpressの勉強を始めるとすぐ、ループとかテンプレートタグとかいう見慣れない言葉に出くわして訳わかんないよ、と思う方も多い思います。 今日はこのうちテンプレートタグについてできるだけ丁寧に説明し、次回ループについて見てみたいと思います。

テンプレートタグとは

テンプレートタグとは、wordpressのコアで用意されている関数のうち、テンプレートファイル内で使用することを意図して、HTMLを出力したり、カテゴリやタグなどで条件分岐したり、部分テンプレートを読み込んだりするものをいいます。要するに関数です。 ここからはwordpress公式の最新テーマTwenty Nineteenを例に具体的に見ていきましょう。

// single.php
<?php
get_header();
?>
    <section id="primary" class="content-area">
        <main id="main" class="site-main">

            <?php
            /* Start the Loop */
            while ( have_posts() ) :
                the_post();
                get_template_part( 'template-parts/content/content', 'single' );
                if ( is_singular( 'attachment' ) ) {
                                    // 中略
                                } elseif ( is_singular( 'post' ) ) {
                                    // 中略
                }
                // 中略
            endwhile; // End of the loop.
            ?>
        </main><!-- #main -->
    </section><!-- #primary -->

<?php
get_footer();

一般テンプレートタグ

一般テンプレートタグとは、主にテンプレートファイル内で使用し、HTMLの出力を生成することを目的とした関数群です。一般テンプレートタグの代表的なものにthe_title()とか、the_content()とかがあります。その名のとおり、それぞれタイトルとコンテンツ(本文)を出力するための関数です。single.phpは個別投稿を表示するためのテンプレートなので、これらのテンプレートタグが書かれていそうなものですが、見てもありませんね。

このテーマでは、template-parts/content/content-single.phpという投稿表示用の部分テンプレートが用意されていて、あとで説明するget_template_part()というインクルードタグによって挿入されていますのがわかります。content-single.phpを見てみると、

// template-parts/content/content-single.php
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <?php if ( ! twentynineteen_can_show_post_thumbnail() ) : ?>
    <header class="entry-header">
        <?php get_template_part( 'template-parts/header/entry', 'header' ); ?>
    </header>
    <?php endif; ?>

    <div class="entry-content">
        <?php
        the_content(
            sprintf(
                wp_kses(
                    /* translators: %s: Name of current post. Only visible to screen readers */
                    __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentynineteen' ),
                    array(
                        'span' => array(
                            'class' => array(),
                        ),
                    )
                ),
                get_the_title()
            )
        );
                // 中略
        ?>
    </div><!-- .entry-content -->
        <!-- 中略 -->
</article><!-- #post-${ID} -->

10行目でthe_content()が呼ばれていますね。the_title()は見当たりませんが、これはさらに部分テンプレートを辿って行った先(template-parts/header/entry-header.php)に書かれています。

余談ですが、single.phpは個別記事を表示するための使われるのに対して、page.phpは固定ページを表示するテンプレートです。Twenty Nineteenのpage.phpを見るとsingle.phpとよく似たつくりになっていて、部分テンプレートを辿っていくとthe_title(), the_content()という記述が見付かると思います。個別記事と固定ページはworpdress上別々の扱いなのに、何故同じテンプレートメソッドが使えるのか疑問に思った方は感がいいです。気になる方はこちらの記事を読んでみてください。

worpdressでよく見る$postとは何なのか

もう一つ余談ですが、template-parts/content/content-single.phpの中で、the_title()と良く似たget_the_title()という関数が出てきました。これはwordpressで良くある関数のペアで、ざっくり言うと、theから始まる関数は実行した場所で出力を行うのに対して、get_theと続く関数は値を取得するだけで出力は行いません。またその他の違いとして、the_title()the_content()などはループの中でしか使えないのに対し、get_the_content()get_the_title()は、引数に投稿オブジェクトを与えてあげればループの外でも機能します。しかしながら、例えばthe_guid()get_the_guid()はどちらもループ外で使用できちゃう、など一般化しにくいところがwordpressの覚えにくいところだったりします。

条件分岐タグ

先ほど、投稿はsingle.php、固定ページはpage.phpを利用すると書きましたが、実はsingular.phpという名前のテンプレート1つでどちらも表示できてしまいます。テンプレート階層について深く知りたい方は、wordpressのテンプレート階層を参照してください。

では、singular.phpを使うとして、固定ページの場合と投稿の場合で一部の表示を出し分けるにはどうすればいいでしょうか?

そういう時に使えるのが条件分岐タグです。条件分岐タグはTRUE/FALSEを返す定義済みの関数で、僕も全部把握してないぐらい沢山あります。困ったときは公式ドキュメントを見るといいです。

wordpressの条件分岐タグ一覧

今回の場合、is_singular()を使えば、以下のような感じに表示を出し分けることができます。

<?php
// singular.php内で投稿タイプによって表示を出し分ける例
if ( is_singular('page') ) {
 echo 'これは固定ページです'
} elseif ( is_singular('post') ) {
 echo 'これは個別投稿ページです'
}

Twenty Nineteenのsingle.phpでもis_singular()が使われていますね。single.phpは個別記事の表示に使われるのですが、アップロード画像なども一種の投稿とみなされてsingle.phpが使われる場合があるのです。なので、現在表示しているのが画像などのattachment投稿タイプか、個別記事(post投稿タイプ)かで表示を出し分ける処理をしています。

なお、条件分岐タグもループの中でしか使えないものがいくつかあるので、ループ外に書いて期待どおりに動かない場合は公式ドキュメントに立ち返ってください。

それと、条件分岐タグはテンプレートタグの一部の扱いですが、実際のところテンプレート内だけじゃなく、function.phpとかで定義した関数の中(フックに登録して処理を書き換える場合など)で使うこともよくあります。ループ内でしか使えない条件分岐タグも、ループ内のテンプレートタグに仕込まれたフックでなら使うことができます。(ちょっと何言ってるかわからないですね) 詳しくはwordpressのフックをマスターしてカスタマイズの幅を広げるをお読みください。

インクルードタグ

例えば、トップページでも個別記事のページでも共通のヘッダーとフッターを表示したいとします。single.phpとhome.phpに同じヘッダー・フッターコードを書くけば実現できますが面倒臭いです。

複数のページで使い回すことが多いヘッダーやヘッダーは部分テンプレートに書いておき、必要な場所でその部分テンプレートを挿入することができれば楽ですよね。

これはphpに元々備わっているinclude()でも実現できますが、wordpressにはもっと簡単に部分テンプレートを読み込める関数(インクルードタグ)が用意されています。

  • get_header()
  • get_footer()
  • get_sidebar()
  • get_template_part()
  • get_search_form()
  • comments_template()

get_header(), get_footer(), get_sidebar()は似たような使い方で、引数を与えないで呼び出した場合、それぞれテーマディレクトリ内のheader.php, footer.php, sidebar.phpを探し、見付かればそのファイルをインクルードします。見付からない場合はwordpressコアに用意されているデフォルトテンプレートが使われるらしいです。

これらの関数は文字列の引数を一つ受け取ることができて、例えばget_header('first')とすると、テーマディレクトリ内のheader-first.phpを探してインクルードしてくれます。ページによってヘッダーやフッターのデザインを変えたり、サイドバーのコンテンツを切り替えたい場合に使ったりします。

次に、Twenty Nineteenのsingle.phpにも登場したget_template_part()は色々な使い方ができますが、一つの投稿表示部分を部分テンプレートに切り出して、ループ内でインクルードするという使い方が多く見られます。

なお、get_template_part()railsのpartialなどと違って、部分テンプレート内で使用するローカル変数を渡すことはできません。 どうしても変数を渡したい場合、別の方法を試しましょう。

次回はループについて説明します!よきwordpressライフを!