クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

ざっくりWordPress:PHP書式とテンプレートタグの識別-前編

PHPの基本を理解するためにJSと比較する」でWordPressは「PHP書式」とWordPress独自の「テンプレートタグ」で構成されていると書きました。そしてPHPの基本書式について解説しました。

これを踏まえてWordPressのコードを見直すと、「テンプレートタグ」が見つけやすくなります。それではさっそくWordPressのコードを見ていきましょう。
前・後編の2回に分けて書きます。前編はWordPressのファイル構成、テンプレートタグのインクルードタグ、WordPressループを見ていきます!

目次:

本稿はPHP書式が出てきます。「PHPって何?」という方はこちら
参考:PHPの基本を理解するためにJSと比較する

WordPressのファイル構成

サーバサイドの中でのWordPressの位置付け」で、WordPressには「テーマ」(デザインテンプレート)と「プラグイン」(拡張機能)があると書きました。

※参考:サーバサイドの中でのWordPressの位置付け

具体的にはどういうファイル構成になっているか見ていきます。
まずはWordPressのファイル一式をダウンロードしてみましょうか。「WordPress」で検索すると一番上に公式ページがありますね。

※参考WordPress公式ページ

右上に「WordPressをダウンロード」があるのでクリック。
f:id:idr_zz:20180109210943j:plain

おっと、別ページになった!いきなりはダウンロードできないらしい。。
ページの中の「WordPress x.x.xをダウンロード」をクリック。(x.x.xは最新バージョン数です)
f:id:idr_zz:20180109211101j:plain

ダウンロードした「wordpress」フォルダを開くとこんな感じです。
見ての通りほとんどが.phpファイルですね。そしていくつかフォルダがある。
私たちが普段カスタマイズで触るのは「wp-content」の中です。
f:id:idr_zz:20180109211255p:plain

「wp-content」の中はこんなん。プラグインが「plugins」、テーマは「themes」ですね。
なお、プラグインはあまりカスタマイズしません。(プラグインのバージョンアップの時に不具合の原因になるため)
それでは「themes」の中を見てみましょうか。
f:id:idr_zz:20180109211348p:plain

「themes」の中はこんなん。あらかじめいくつかのフォルダが入っていますね。これらはWordPressの「デフォルトテーマ」と言います。
例えば「Twenty Seventeen」は「2017年版のデフォルトテーマ」を意味します。
f:id:idr_zz:20180109212217p:plain

「Twenty Seventeen」の中を見てみましょう。こんなです。.phpファイルがたくさん入っていますね。
まずはトップページのファイルindex.phpの中を見てみましょう。 f:id:idr_zz:20180109212025p:plain

index.phpのコード

下記がindex.phpのコードです。

<?php
/**
 * The main template file
 *
 * This is the most generic template file in a WordPress theme
 * and one of the two required files for a theme (the other being style.css).
 * It is used to display a page when nothing more specific matches a query.
 * E.g., it puts together the home page when no home.php file exists.
 *
 * @link https://codex.wordpress.org/Template_Hierarchy
 *
 * @package WordPress
 * @subpackage Twenty_Seventeen
 * @since 1.0
 * @version 1.0
 */

get_header(); ?>

<div class="wrap">
    <?php if ( is_home() && ! is_front_page() ) : ?>
        <header class="page-header">
            <h1 class="page-title"><?php single_post_title(); ?></h1>
        </header>
    <?php else : ?>
    <header class="page-header">
        <h2 class="page-title"><?php _e( 'Posts', 'twentyseventeen' ); ?></h2>
    </header>
    <?php endif; ?>

    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">

            <?php
            if ( have_posts() ) :

                /* Start the Loop */
                while ( have_posts() ) : the_post();

                    /*
                    * Include the Post-Format-specific template for the content.
                    * If you want to override this in a child theme, then include a file
                    * called content-___.php (where ___ is the Post Format name) and that will be used instead.
                    */
                    get_template_part( 'template-parts/post/content', get_post_format() );

                endwhile;

                the_posts_pagination( array(
                    'prev_text' => twentyseventeen_get_svg( array( 'icon' => 'arrow-left' ) ) . '<span class="screen-reader-text">' . __( 'Previous page', 'twentyseventeen' ) . '</span>',
                    'next_text' => '<span class="screen-reader-text">' . __( 'Next page', 'twentyseventeen' ) . '</span>' . twentyseventeen_get_svg( array( 'icon' => 'arrow-right' ) ),
                    'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentyseventeen' ) . ' </span>',
                ) );

            else :

                get_template_part( 'template-parts/post/content', 'none' );

            endif;
            ?>

        </main><!-- #main -->
    </div><!-- #primary -->
    <?php get_sidebar(); ?>
</div><!-- .wrap -->

<?php get_footer();

ぐぬぬ…いきなりいろんな書式のコードがたくさんですね(汗)。面食らうなぁ。
まずはこの中から「HTMLのみ」を抜き出してみましょう。下記のような構成になります。
なお、headerが2つあるのはPHPのif文で分岐するためです。

<!--HTMLのみ-->

<div class="wrap">
        <header class="page-header">
            <h1 class="page-title"></h1>
        </header>
    <header class="page-header">
        <h2 class="page-title"></h2>
    </header>

    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">
            <span class="screen-reader-text"></span>
            <span class="screen-reader-text"></span>
            <span class="meta-nav screen-reader-text"></span>
        </main><!-- #main -->
    </div><!-- #primary -->
</div><!-- .wrap -->

ここに「PHP書式」を加えるとこうなります。なお、後述する「テンプレートタグ」はここではざっくりした日本語に置き換えています。

<!--HTMLとPHP-->

<?php ヘッダー処理 ?>

<div class="wrap">
    <?php if (条件) : ?>
        <header class="page-header">
            <h1 class="page-title"><?php タイトル処理 ?></h1>
        </header>
    <?php else : ?>
    <header class="page-header">
        <h2 class="page-title"><?php タイトル処理 ?></h2>
    </header>
    <?php endif; ?>

    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">

            <?php
            if (条件) :
                while (条件) : the_post();
                    コンテンツ処理
                endwhile;

                ページネーション処理 ( array(
                    キー =>'<span class="screen-reader-text"></span>',
                    キー =>'<span class="screen-reader-text"></span>',
                    キー =>'<span class="meta-nav screen-reader-text"></span>',
                ) );
            else :
                コンテンツ処理
            endif;
            ?>

        </main><!-- #main -->
    </div><!-- #primary -->
    <?php サイドバー処理 ?>
</div><!-- .wrap -->

<?php フッター処理
  • 一番最初のPHPには「ヘッダー設定」が入ります。
  • .wrapの最初にif文でheaderが2つに分岐しています。
  • #primaryおよびmainの中にはまず「コンテンツ処理」が入っています。while文で反復しています。
     次に「ページネーション処理」が入ります。array配列の中にspan要素が埋め込まれています。
  • #primaryの下のPHPに「サイドバー設定」が入ります。
  • 一番最後のPHPに「フッター設定」が入ります。PHP終了タグは省略されています。

WordPressのテンプレートタグ

index.phpのコードの中には見かけない関数がたくさん出てきます。これらは「テンプレートタグ」と言って、WordPressのシステムの中に定義されている独自の関数です。

index.phpのコードのシンタックスハイライトの色が付いていない黒字の関数がテンプレートタグです。上から順に get_header()is_home()is_front_page() …などです。

テンプレートタグはPHPの組み込み関数ではないため、WordPress以外のPHPファイルでは認識しません。位置付けとしては「JSのライブラリとフレームワーク」で触れたJSの「ライブラリ」の「メソッド」と似ています。

  • JS > jQuery(=ライブラリ)> jQueryのメソッド
  • PHP > WordPress(=CMS) > WordPressのテンプレートタグ

f:id:idr_zz:20180110010616j:plain

※参考:【卒jQueryへの道】生JSとライブラリとフレームワークの理解

それでは代表的なテンプレートタグを見ていきましょう。

インクルードタグ

インクルードタグ」は、CMSサイト全体の共通パーツ(ヘッダーなど)を外部ファイル化(header.phpなど)し、ページにインクルード(読み込み)するタグです。
これによって例えばヘッダーの修正が生じた時にはheader.phpの一箇所を修正するだけでサイト全体に適用されます。

※主なインクルードタグ :get_で始まります。

  • get_header():ヘッダーheader.php読み込み
  • get_sidebar():サイドバーsidebar.phpを読み込む
  • get_footer():フッターfooter.phpを読み込む
  • get_template_part():その他のパーツ。引数の中のPHPファイルを読み込む

f:id:idr_zz:20180110011955j:plain

WordPressループ

WorePressループ」は投稿一覧を表示する時に重要な「制御構造」です。該当ページに投稿があるか判定し、投稿数の回数ループして表示します。*1

下記のような構造です。

//WordPressループ
<?php 
if ( have_posts() ) :
    while ( have_posts() ) : 
        the_post(); 
        //投稿内容
    endwhile;
endif;
?>
  • if文(分岐)の中にwhile文(反復)が入っています。
  • if文とwhile文の条件式の中にはhave_posts()というテンプレートタグがあります。
    投稿がある時に分岐や反復を実行する、という意味になります。
  • while文のブロック文の最初にthe_post()というテンプレートタグがあります。 これは「次の投稿を取得する」という役割になり、ブロック文の内容を実行した後に、次の投稿に進んで同じブロック文を実行します。

index.phpmain要素の中に下記のようなWordPressループがあります。(一部省略)

<?php
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        get_template_part( 'template-parts/post/content', get_post_format() ); 
    endwhile;
    the_posts_pagination( array(ページネーション設定) );
else :
    get_template_part( 'template-parts/post/content', 'none' );
endif;
?>
  • このWordPressループのif文はelseで分岐しています。(elseがない場合はifの条件式に合致しない場合何もしない)
  • while文の中にはget_template_part()というインクルードタグがあり、template-parts/post/ディレクトリの中のcontent.phpをインクルードします。
  • その下のthe_posts_pagination()はページネーションを出力するテンプレートタグです。引数には「ページネーション設定」の配列arrayが入っています。
  • if文elseで投稿がないときににget_template_part()template-parts/post/ディレクトリの中のcontent-none.phpを読み込みます。

引数の中のテンプレートタグの詳細はこちら
※参考:get_template_part( ‘content’, get_post_format() );はcontent.phpをincludeする
※参考:WordPressにページネーションを入れる方法

なお、省略した「ページネーション設定」などの中にも様々なテンプレートタグが入っています。詳細はこちらを参照ください。

※参考:テンプレートタグ - WordPress Codex 日本語版
(ただし、twentyseventeen_get_svg()などテーマの中に定義された独自の関数もあり、他のテーマに変更すると反映されません)

最後に

私はHTML→CSS→JS(というかjQuery)と進んだあと「どうやらCMSというものがあるらしいぞ」とWordPressに挑戦。*2
ダッシュボードでブログのように投稿ができることに感動し、メニュー名やカテゴリ名を一気に編集できることにまた感動。*3

さあ次は自作テーマに挑戦だ!という段階で独特なPHP書式の塊に戸惑いました。ネット上の先人たちのコードをかき集めたパッチワークコードで乗り切ったものでした。 もし先にPHPの基礎を理解していたらこんなに回り道をしていなかったかもな〜と思っています。

後編は「Twenty Seventeen」の別のファイルや、プラグインのコードなども見ていきたいと思います。それでは!

(後編書きました!)
※参考:ざっくりWordPress:PHP書式とテンプレートタグの識別-後編


※参考:サーバサイドの基本まとめました!
【WordPress、PHP、SQL文】Webデザイナーでもわかるサーバサイドの基本まとめ!(6記事) - クモのようにコツコツと idr-zz.hatenablog.com

※参考:【WordPress、PHP、SQL文】サーバサイドの基本まとめ
qiita.com

*1:「メインループ」とも言います。他に、サイドバーなどに別ページの投稿を表示する「サブループ」もあります。「WP_Query」などの書式です。

*2:Movable Typeの存在も知ってはいたが未経験

*3:HTMLサイトでメニュー変更なんてあったらコピペの嵐