Go to top Go to bottom

「テーマを作成する」と聞くと、ちょっとハードルが高いような印象を受けるかもしれません。たしかに、きちんと細部までこだわったテーマを作成したり、あるいは少し特殊なことを実装しようとすると、やはりたくさんの知識が必要になります。しかし、単に普通のサイト用のテーマを作るだけであれば、意外に簡単にできてしまいます。WordPressはよくできたソフトウェアですので、あらゆることがなるべく簡単にできるよう設計されていますし、それゆえに世界中で普及しているという事実もあります。

この記事では、簡単なブログ用のテーマを作成しながら、テーマの作り方を順を追ってみていきたいと思います。初心者の方にもなるべくわかりやすいように解説していきますので、ぜひご自身でも手を動かしながら読んでみてください! また、今回作成するサンプルテーマはダウンロードすることができますので、わからなくなったらその都度参考にしていただければと思います。

テーマを作成する前に

WordPressが動く環境を準備しよう

WordPress
WordPress

テーマ作成を行うためには、WordPressを動かすための環境が調っている必要があります。もしまだ環境がない方は、次の2つの記事を参考に、WordPressをローカル(自分のPC)で動かす準備を行っておいてください。

サンプルテーマのダウンロード

今回作成するテーマは以下の場所からダウンロードすることができます。テーマフォルダに展開すれば、実際に使用することもできます。

ライセンスはGNU General Public Licenseです。ご自由にお使いください。

どんなサイトを作るか考えよう

実際にコードを書く前に、どんなサイトにするかをおおまかに考えておきましょう。WordPressでテーマを作るためにはたくさんのファイルが必要になってきますが、このファイル構成はサイトの内容に大きく依存します。

今回は、下の画像のような、とてもシンプルなブログサイトを構築してみたいと思います。WordPressはもともとブログを作成するために生み出されたものですので、ブログサイト用のテーマを作ることはWordPressを理解する上でとても効率のよい学習方法だといえます。

今回作成するブログサイトのトップページ
今回作成するブログサイトのトップページ

上の図が今回作成するブログのトップページです。あまり余計なものを入れず、とても単純な構成にしてあります。トップページ以外の構成は次の図の通り、記事を閲覧する「個別ページ」と、ブログ以外の内容を記載する「固定ページ」の2つしかありません。

サイトの構成
サイトの構成
  • トップページはブログ記事の一覧
  • ブログ記事をクリックしたら、記事の内容を表示
  • 固定ページを使って、About(サイトについて)を作成

実際に自分でテーマを作るときは、大体のレイアウトとサイト構成をあらかじめ考えておきましょう。特に、レイアウトは後から変えるとなると結構大変です。手書きでも構いませんので、どこに何を表示するかを決めておいてください。

トップページを作成するのに必要なファイルを把握しよう

WordPressのテーマは、最低限style.cssとindex.phpがあれば動かすことができます(この記事で解説しています)。ただ、実際にサイトを作るとなると、他にもいくつかのファイルが必要になります。

テンプレートをパートに分割
テンプレートをパートに分割

トップページ全体はindex.phpのテンプレートで作成しますが、その中のパーツを次の3つに分割します。

1 header.php(必須)各テンプレートで共通なHeader部分を出力する
2 footer.php(必須)各テンプレートで共通なFooter部分を出力する
3 sidebar.php必要なテンプレートでサイドバーを出力する

ページを出力するために使われるindex.phpやsingle.phpがテンプレートと呼ばれるのに対し、テンプレートが呼び出して使うパーツのことをテンプレートパートと言います。トップページはこのindex.phpが、header.php、footer.php、sidebar.phpを読み込むことで出来上がるわけですね。

テンプレートでテンプレートパートを読み込む
テンプレートでテンプレートパートを読み込む

こうすることで、各ページで同じような見た目、あるいは各テンプレートで同じような処理を毎回記載する手間が省け、効率よくブログサイトを作成することができます

残った記事一覧の部分については、index.phpに直接処理を書きます。この部分もテンプレート化することができますが、今回は行いません。

最終的に、トップページを作成するには次の4つのPHPファイルが必要になることがわかりました。

  • index.php
  • header.php
  • footer.php
  • sidebar.php

どのサイトを作るにしても、最初の3つは必ず必要になります。sidebar.phpもたいていのウェブサイトには導入されると思いますが、ウィジットの機能を全く使わないなら不要です。

各ページでヘッダー部分が少し違う場合はどうすればいいの?

ヘッダーを共通化すると、各ページで全く同じ見た目の内容が表示されることになります。ところが、たとえばトップページと個別ページでデザインを変えたい場合はどのようにしたらよいか、という疑問が生まれます。

このような場合は「条件分岐タグ」と呼ばれる関数を使って、トップページの場合はこのデザイン、個別ページの場合はこのデザインというように出力を変えることができます。ヘッダーに限らず、「条件分岐タグ」はどのテンプレートでも使うことができます。

必要なファイルを揃えて、テーマを有効化しよう

どのようなファイルが必要かわかったので、今度は実際にテーマに必要なファイルを作成し、有効化してみましょう。

WordPressのファイル編集にメモ帳は使えません

ファイルを作成・編集するときは、Windowsのメモ帳は使えませんので、Sublime TextAdobe Bracketなど別のアプリケーションを利用してください。BOMなしのUTF-8形式で保存できるテキストエディタであればなんでも構いません。

テーマフォルダに必要なファイルを保存する

テーマフォルダを作成し、必要なファイルを保存する
テーマフォルダを作成し、必要なファイルを保存する

WordPressのテーマフォルダを開きます。XAMPPを利用している場合は、次の場所にあります。

PATH

C:\xampp\htdocs\your-site-name\wp-content\themes

この中にまず、テーマ用のフォルダを作成します(フォルダ名は小文字の英数字とハイフンだけが使用できます)。なるべくほかのテーマと被らないような名前を付けることをおすすめします。

次に、作成したフォルダの中に次の6つのファイルを保存してください。中身は空で構いません

  • style.css
  • index.php
  • header.php
  • footer.php
  • sidebar.php
  • functions.php

スタイルシートに必要な情報を記載する

テーマフォルダに保存したstyle.cssを開き、次のようなコメントを記載します。

/*
  Theme Name:   テーマの名前(必須)
  Description:  テーマの説明
  Theme URI:    テーマのURL
  Author:       作成者の名前
  Author URI:   作成者のURL
  Version:      テーマのバージョン番号
  License:      ライセンス
  License URI:  ライセンスのURL
*/

これはテーマに関する基本的な情報で、スタイルシートヘッダと呼ばれます。テーマの名前は必須ですが、それ以外は任意です。配布する際などはCodexを参考に、すべて記載しておいた方が良いでしょう。

今回は次のようにしてみました。

/*
  Theme Name:   White Snow
  Description:  Just a sample theme aiming to learn how to create wordpress theme
  Theme URI:    https://thewppress.com/theme/how-to-create-the-basic-wordpress-theme/
  Author:       Naotoshi Fujita
  Author URI:   thewppress.com
  Version:      1.0
  License:      GNU General Public License v3 or later
  License URI:  https://www.gnu.org/licenses/gpl-3.0.html
*/

SCSSなどを使う場合は、/*! Comment */とするなどしてビルドの際にコメントが削除されないよう気を付けてください。

テーマを有効化する

準備が調ったら、WordPressの管理画面に移動し、[外観]の[テーマ]をクリックしてください。

テーマを有効化
テーマを有効化

画像は表示されていませんが、テーマとして認識されていることがわかります。作成したテーマの上にカーソルを移動し、[有効化]ボタンをクリックしてください。実際にサイトを確認すると、画面が真っ白になっていて、何も表示されていないはずです。この状態になっていれば、テーマが有効化されています。

ちなみに、画像を表示させるにはscreenshot.pngというファイルを自分のテーマフォルダの中に入れておきます。画像サイズは880660が推奨されています。

screenshot.pngを用意するとプレビューに表示される
screenshot.pngを用意するとプレビューに表示される

HTMLの骨格を作ろう

テーマを有効化しても、中身が何もないので真っ白なままですね。今度は、HTMLの大まかな骨格を作成していきます。index.phpを開いて、トップページを意識しながら普通のHTMLとしてコーディングしてみてください。

トップページには、大きくヘッダー、コンテンツ、サイドバー、そしてフッターの4つのブロックが存在しますので、たとえば次のようにコーディングすることができます。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>

<body>
<div id="page" class="site">
  <div id="container" class="site-container">
    <header id="main-header" class="site-header">
      <div class="site-branding">
        ロゴやキャッチフレーズ
      </div>

      <nav id="main-navigation" class="site-navigation" role="navigation">
        メニュー
      </nav>
    </header>

    <div id="content" class="site-content">
      <div id="primary" class="content-area">
        コンテンツ
      </div>

      <aside id="secondary" class="sidebar" role="complementary">
        サイドバー
      </aside>
    </div>

    <footer id="footer" class="site-footer">
      フッター
    </footer>
  </div>
</div>
</body>
</html>

Wrapper用の<div>idclassはお好きなように変更していただいて構いません。ただし、<head>タグの中身は今の時点ではcharsetのみにとどめておいてください。普段は必要となる<title>タグも不要です。

この状態でサイトを確認してみましょう。

いつも通りのHTMLで作成したページを確認
いつも通りのHTMLで作成したページを確認

入力した内容が表示されていれば成功です。この時点では、あまり細かく作りこむ必要はありません。ページの骨格が大体定義できれば問題ないと思います。

HTMLを分割しよう

今度は、index.phpに書いたHTMLをheader.phpとfooter.phpに分割します。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>

<body>
<div id="page" class="site">
  <div id="container" class="site-container">
    <header id="main-header" class="site-header">
      <div class="site-branding">
        ロゴやキャッチフレーズ
      </div>

      <nav id="main-navigation" class="site-navigation" role="navigation">
        メニュー
      </nav>
    </header>

    <div id="content" class="site-content clearfix">
      <div id="primary" class="content-area">
        コンテンツ
      </div>

      <aside id="secondary" class="sidebar" role="complementary">
        サイドバー
      </aside>
    </div>

    <footer id="footer" class="site-footer">
      フッター
    </footer>
  </div>
</div>
</body>
</html>

各ページによって「共通な部分はどこか」「変わる部分はどこか」を意識しながら分割します。今回は1~20行目の<div id="content">を開くところまではどのページでも共通です。また、この<div>を閉じるところから最後までの28~36行目までも同じです。この前半をheader.phpに、後半をfooter.phpに移動して保存します。

header.phpに切り取った前半を移動

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>

<body>
<div id="page" class="site">
  <div id="container" class="site-container">
    <header id="main-header" class="site-header">
      <div class="site-branding">
        ロゴやキャッチフレーズ
      </div>

      <nav id="main-navigation" class="site-navigation" role="navigation">
        メニュー
      </nav>
    </header>

    <div id="content" class="site-content">

footer.phpに切り取った後半を移動

    </div> <!-- #content -->

    <footer id="footer" class="site-footer">
      フッター
    </footer>
  </div> <!-- #container -->
</div> <!-- #page -->
</body>
</html>

開くタグと閉じるタグを分割すると、何を閉じているのかが分からなくなるので、上のようにコメントを残しておくことをおすすめします

さて、前半と後半を切り取ったので、index.phpは次のコードだけが残りました。

<div id="primary" class="content-area">
  コンテンツ
</div>

<aside id="secondary" class="sidebar" role="complementary">
  サイドバー
</aside>

このままでは当然、切り取った前半と後半が出力されなくなってしまいます。そこで、header.phpとfooter.phpを読み込む処理を書きます。

<?php get_header(); ?>

<div id="primary" class="content-area">
  コンテンツ
</div>

<aside id="secondary" class="sidebar" role="complementary">
  サイドバー
</aside>

<?php get_footer(); ?>

もともと前半のコードがあった部分にget_header()を、後半のコードがあった部分にget_footer()を記載しました。それぞれheader.phpとfooter.phpを読み込むための関数(テンプレートタグ)です。

完成したら、サイトを確認してみてください。HTMLで書いたときと全く同じ表示になっていれば成功です。念のため、ブラウザの「ソースを確認」する機能を使って、タグが正しく出力されているかも確認しておいた方が安心です。

ブラウザでソースを確認
ブラウザでソースを確認

header.phpとfooter.phpに必要な関数を記載しよう

header.phpとfooter.phpには、必ずWordPressの関数を入れる必要があります。まず、header.phpのheadタグを閉じる前に、wp_head()を挿入します

header.php

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <?php wp_head(); ?>
</head>

次に、footer.phpでbodyタグを閉じる直前に、wp_footer()を加えます

footer.php

    <footer id="footer" class="site-footer">
      フッター
    </footer>
  </div> <!-- #container -->
</div> <!-- #page -->

<?php wp_footer(); ?>
</body>
</html>

これらはWordPressの大事な機能を実行するために必要ですので、忘れないように記載しておきましょう。

この状態でサイトを確認すると、アドミンバーが表示されるようになります。

アドミンバーが表示された
アドミンバーが表示された

またHTMLのソースを確認すると、自分では書いていないたくさんのタグやコードが出力されていることがわかります。

wp_head()によりたくさんのコードが出力される
wp_head()により、たくさんのコードが出力される

スタイルシートを読み込もう

現状、CSSファイルを読み込んでいないので、スタイルを適用することができません。そこで、スタイルシートを読み込む処理を記述します。通常、静的なウェブサイトを作る際は、linkタグを直接head内に記載してCSSを読み込みますが、WordPressでは関数を使ってスタイルシートを読み込みます

functions.phpを開いて次のようなコードを記載してください。

<?php

/*
 * Enqueue styles and scripts.
 */
function whitesnow_enqueue_scripts() {
  // Load theme style.
  wp_enqueue_style( 'whitesnow-style', get_stylesheet_uri() );
}

add_action( 'wp_enqueue_scripts', 'whitesnow_enqueue_scripts' );

6行目と11行目の”whitesnow”の部分は自分のテーマの名前を省略したもので置き換えてください。接頭辞を付けるのは、ほかのプラグインなどの関数と名前がかぶるのを防ぐためです。ただ、あまり長いと使いにくいので、たとえばMinimalというテーマ名ならmnmlとしてもよいと思います。

8行目のwp_enqueue_style()スタイルシートを読み込むための関数です。第1引数が、'whitesnow-style'となっていますので、自分のわかりやすい識別子(名前)に変更してください。第2引数のget_stylesheet_uri()はstyle.cssまでのURLを取得する関数です。詳しくはこのライブラリで解説しています。

functions.phpにはPHPコードを記載するため、第1行目に<?php(PHPコードを始めますという宣言)が必要です。

逆に、ファイルの終わりには通例?>(PHPコードの終了を宣言)を書きません。書いても問題ありませんが、書く場合は?>の後に一切のスペースや改行が入らないよう注意してください。スペースなどが入っていると、思わぬところでバグが発生します(たとえばプラグインがうまく動かなくなるなど)。ミスを避けるため、書かない方が得策です。

これでスタイルシートを読み込むことができました。ソースコードを確認すると、スタイルが正しく読み込まれていることがわかります。

スタイルシートが読み込まれていることを確認
スタイルシートが読み込まれていることを確認

スタイルを適用して、ヘッダーとフッターをスタイリングしてみよう

スタイルが読み込めましたので、ヘッダーとフッターの体裁を整えておきましょう。一般的なウェブサイトを作成するときとほとんど同じですが、画像へのパスやリンクを挿入するときに注意が必要です

header.phpを調整する

ヘッダー部分にはサイトのロゴ、キャッチフレーズ、ナビゲーションの3つの要素があります。

ヘッダー部分
ヘッダー部分

ナビゲーションはひとまずおいておき、ロゴとキャッチフレーズを表示してみましょう。ロゴをクリックしたらフロントページに戻る機能もつけてみたいと思います。

ロゴ画像を表示する

テーマフォルダの中にimagesというフォルダを用意し、その中にロゴの画像ファイルを保存しておいてください。

通常、画像をHTMLで読み込むには<img src="画像までのパス">と記述しますね。静的なウェブサイトを作成する際はよく相対パスを使用しますが、WordPressでは画像までの完全なURLを記述する必要があります。ただ、テーマを使うサイトによってURLは変わってしまうため、http://…のように手動で記載するわけにはいきません。

そこで、テーマフォルダまでのURLを取得できる関数get_template_directory_uri()を利用します(詳細はライブラリを参照してください)。

<div class="site-logo">
  <img src="<?php echo get_template_directory_uri(); ?>/images/logo.png">
</div>

ロゴはimagesフォルダに保存しましたので、get_template_directory_uri()に続けて、images/logo.pngと記載しています。

さらに、<a>タグを利用して、ロゴ画像にフロントページまでのリンクを挿入してみましょう。

<div class="site-logo">
  <a href="<?php echo esc_url( home_url( '/' ) ); ?>">
    <img src="<?php echo get_template_directory_uri(); ?>/images/logo.png">
  </a>
</div>

home_url()は、サイトのトップページまでのURLを返す関数です。esc_url()はURLを無害化する関数ですが、今はよくわからなくてもこのまま書いてもらえれば問題ありません(詳細はライブラリをご参照ください)。

ロゴはカスタムロゴを使った方が便利

今回は簡単のため、ロゴを通常の画像の読み込みと同じ方法で実装していますが、実際には「カスタムロゴ」という機能を使ったほうが後々便利です。

キャッチフレーズを表示する

キャッチフレーズは、管理画面の[設定]→[一般設定]にある「サイトの簡単な説明」です。説明文を入力したら、設定を保存しておきましょう。

管理画面におけるキャッチフレーズ
管理画面におけるキャッチフレーズ

キャッチフレーズを表示するには、bloginfo()という、サイトの情報を出力できる関数を使用します。

<div class="site-tagline">
  <?php bloginfo( 'description' ); ?>
</div>

bloginfo()の引数に'description'を渡すことで、キャッチフレーズが出力されます(echoは不要です)。

あとはCSSを記載してスタイルを調整すれば、ヘッダーが出来上がります!

調整済みのヘッダー部分
調整済みのヘッダー部分

header.phpの内容と補足

ここまでの内容を全て記載したheader.phpは次のようになります。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
<div id="page" class="site">
  <div id="container" class="site-container">
    <header id="main-header" class="site-header">
      <div class="site-branding">
        <div class="site-logo">
          <a href="<?php echo esc_url( home_url( '/' ) ); ?>">
            <img src="<?php echo get_template_directory_uri(); ?>/images/logo.png">
          </a>
        </div>

        <div class="site-tagline">
          <?php bloginfo( 'description' ); ?>
        </div>
      </div>

      <nav id="main-navigation" class="site-navigation" role="navigation">
        メニュー
      </nav>
    </header>

    <div id="content" class="site-content">

スタイルを当てやすくするため、bodyにはbody_class()を付記しています。この関数は、現在のページに応じて自動でクラスを振り分けてくれる便利な関数ですので、忘れずに記載しておきましょう。どのようなクラスが追加されるかはこのライブラリで解説しています。

footer.phpを調整する

フッターはとてもシンプルですが、サイトのタイトルを表示するのに関数を使用します。

フッター部分
フッター部分

サイトのタイトルは、管理画面の[一般設定]で設定されています。

管理画面のサイトタイトル
管理画面の「サイトのタイトル」

ウェブサイトでサイト名を表示するときは、直接記述せず、この設定を出力するようにします。そうすることで、後でサイト名を変えたときにコードの修正をする必要がなくなります。

<footer id="footer" class="site-footer">
  <?php bloginfo( 'name' ) ?>, All rights reserved.
</footer>

キャッチフレーズを表示するときに使用したbloginfo()関数に'name'を渡すと、サイトのタイトルが表示されます。

最後に、ここまでのfooter.phpを記載しておきます。

    </div> <!-- #content -->

    <footer id="footer" class="site-footer">
      <?php bloginfo( 'name' ) ?>, All rights reserved.
    </footer>
  </div> <!-- #container -->  
</div> <!-- #page -->

<?php wp_footer(); ?>  
</body>
</html>

アイキャッチ画像を有効化して、記事を投稿しておこう

ここまでの手順で、ヘッダーの一部とフッター部分が完成しました。今度は記事の一覧に取り掛かります。

記事の一覧ページに表示される投稿
記事の一覧ページに表示される投稿

投稿を見てみると公開日、タイトル、抜粋文など様々な要素がありますが、このうちアイキャッチ画像(Featured Image)はデフォルトの状態で有効になっていません。記事の一覧を表示するコードを書く前に、次の2つの準備をしておきましょう。

  1. テーマでアイキャッチ画像を有効にする
  2. 記事を投稿する

アイキャッチ画像を有効化する

アイキャッチ画像を有効化するには、functions.phpに次のように記載します。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
} 

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );

先ほどfunctions.phpにスタイルを読み込むコードを記載しましたので、そのあとに記載することになるでしょう。このコードのうち、6行目が「テーマでアイキャッチ画像を有効化する」命令です。7行目はアイキャッチ画像のサイズを指定する処理で、第1引数が幅、第2引数が高さです。値は適宜調整してください。

これらの関数の詳しい解説は次のライブラリを参考にしてください。

これでアイキャッチ画像を設定できるようになりました。

記事を投稿しよう

記事の一覧を表示するには、当然記事が投稿されている必要があります。簡単で構いませんので、ダミーの記事を数件投稿しておきましょう。

記事を追加するには、管理画面の[投稿]から[新規追加]をクリックします。

新規投稿
新規投稿

投稿画面の説明はこの記事を参照してください。最低限、次の4つの手順を踏みます。

  1. 投稿のタイトルを記載する
  2. 投稿の本文を記載する
  3. アイキャッチ画像を設定する
  4. 記事を公開する

3の「アイキャッチ画像」が表示されていない場合は、アイキャッチの有効化がうまくいっていません。1つ上のセクションを確認してください。

なお、「続きを読む」リンクを表示するためには「続きを読む」タグを記載しておく必要があります。

記事の一覧を表示しよう

記事が投稿されたので、ウェブサイトにその一覧を表示してみましょう。index.phpを編集します。

WordPressループ

現在、index.phpは次のようになっているはずです。

<?php get_header(); ?>

<div id="primary" class="content-area">
  コンテンツエリア
</div>

<aside id="secondary" class="sidebar" role="complementary">
  サイドバー
</aside>

<?php get_footer(); ?>

この4行目に記事一覧を表示する命令を記載していくのですが、記事一つひとつをHTMLタグで記載していくわけにはいきません。「繰り返し処理」を使うことで、一気に表示します。

<?php if( have_posts() ) : ?>
  <?php while( have_posts() ) : the_post(); ?>    
    1つの記事に対する処理の内容をここに書く
  <?php endwhile; ?>
<?php endif; ?>

ちょっと複雑に見えますね。今はこう書くものだという感じで覚えてしまって問題ありません。

この一連の処理は「WordPressループ」と呼ばれ、記事がある限り3行目が何度も実行されます。この中に、テンプレートタグと呼ばれる関数を用いて、投稿の情報を表示していきます。

たとえば、投稿のタイトルを表示するには、the_title()というテンプレートタグを使います。実際にやってみましょう。

<div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
    <?php if( have_posts() ) : ?>
      <?php while( have_posts() ) : the_post(); ?>    
        <?php the_title(); ?>
      <?php endwhile; ?>
    <?php else: ?>
      <!-- 記事が見つからなかったときの処理を書く -->
    <?php endif; ?>
  </main>
</div>

ウェブサイトを確認してみて、記事のタイトルがいくつか表示されていれば成功です(タグを入れていないので、改行されずに1行で表示されてしまうと思います)。

1つの投稿に必要な要素と、対応するテンプレートタグ

1つの投稿は、いくつかの要素で構成されます。それぞれの要素を表示するためのテンプレートタグをまとめると次のようになります。

投稿の日付the_date()
(ただし、同日を出力できないので、echo get_the_date()を使う)
投稿のタイトルthe_title()
アイキャッチ画像the_post_thumbnail()
本文の一部のプレビューthe_content()
(抜粋機能を使う場合はthe_excerpt()

それぞれのタグはリンク先で詳しく解説しています。これらを使って、先ほどのコードを修正してみましょう。

<div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
    <?php if( have_posts() ) : ?>
      <?php while( have_posts() ) : the_post(); ?>    
        <article> 
          <header>
            <time><?php echo get_the_date(); ?></time>
            <?php the_title(); ?>     
          </header>

          <?php the_post_thumbnail(); ?>
          <?php the_content(); ?>
          </div>
        </article> 
      <?php endwhile; ?>
    <?php else: ?>
      <!-- 記事が見つからなかったときの処理を書く -->
    <?php endif; ?>
  </main>
</div>

ウェブサイトを確認すると、日付や本文の一部が表示されていると思います。

記事の出力を確認
記事の出力を確認

個別ページに遷移できるようにリンクをつけよう

クリックして別のページに遷移させるには、<a>タグを使います。この点は通常のウェブサイト作成と変わりませんが、記事のURLが必要になります。

ある記事の個別ページのURLは、the_permalink()を用いて出力します。文字列として取得するだけなら、get_permalink()を使用します。

アイキャッチ画像にリンクをつけよう

アイキャッチ画像にリンクをつけるには、次のようにします。

<a href="<?php the_permalink(); ?>">
  <?php the_post_thumbnail(); ?>
</a>

hrefの中にthe_permalink()を用いて個別ページのURLを出力しています。

(さらに…)を変更しよう

記事の抜粋文の後に「(さらに…)」という、文字が表示されていますね(表示されていない場合は、本文に「続きを読む」タグが挿入されていません)。クリックすると個別ページに遷移することができますが、このままでは意味が分かりにくいのと、スタイリングしにくいので、次のようにしてカスタマイズしておきます。

<?php the_content( '<span class="btn btn-primary">Continue Reading</span>' ); ?>

the_content()は本文を表示するためのテンプレートタグですが、この第1引数に文字列を指定すると、「(さらに…)」を置き換えることができます。HTMLのタグも併せて入れておけば、好きな見た目に変更することができますね。

なお、この「続きを読む」ためのリンクをクリックすると、自動的に続きの部分にジャンプしてしまいます。WordPressが自動でアンカーを振ってくれているのですが、一般的には記事の先頭に移動してほしいですよね。ただ、なぜか簡単に実装できるようになっていません。仕方ないので、functions.phpに次のように記載します。

/*
 * Remove #more-000 anchor from the read-more link.
 */
function whitesnow_remove_more_link_anchor( $link ) {
  $link = preg_replace( '/#more-[0-9]+/', '', $link );
  return $link;
}

add_filter( 'the_content_more_link', 'whitesnow_remove_more_link_anchor' );

フィルターフックを用いて、リンクの文字列からアンカーを取り除いています。内容が少し難しいので、このままコピー&ペーストしてください(whitesnowの部分は適宜変更してください)。

抜粋文を自動生成にする

投稿の一覧が表示されているページでは、記事の冒頭の一部を短く表示するサイトが多いと思います。the_content()は「続きを読む」タグ以前を表示するよう設計されているので、この需要を満たすことができますが、「文字数が一定にならない」「いちいち続きを読むタグを入れるのが手間、または入れ忘れる」といった問題もあります。

このようなときは、ある一定の文字数で抜粋を自動生成することのできる、the_excerpt()が便利です。使い方については次の2つのライブラリを参考にしてください。

なお、single.phpなどの個別ページテンプレートではthe_content()を使用します。index.phpからsingle.phpに処理をコピーする場合は注意してください。

タイトルをhタグで囲んで、個別ページへのリンクをつけよう

タイトルはthe_title()で出力できるので、hタグで囲うには<h2><?php the_title(); ?></h2>とすればいいように思えます。このようにしても特に問題にはなりませんが、the_title()タイトル前後に表示する文字列を第1引数と第2引数に設定するよう設計されています。

<?php the_title( '<h2>', '</h2>' ); ?>

こうしておくと、仮にタイトルがなかった場合、空の<h2>タグが残ってしまうのを防ぐことができます。

同じようにして、タイトルをクリックしたら個別ページに遷移できるよう、リンクをつけることもできます。

<?php the_title( 
  '<h2 class="heading-big entry-title"><a href="' . esc_url( get_permalink() ) . '">',
  '</a></h2>'
); ?>   

esc_url()はURLを無害化する関数、get_permalink()は投稿ページへのリンクを文字列として取得する関数でしたね。これを.によって連結して第1引数としています。

get_permalink()を使用する際はesc_url()で無害化したほうが安心ですが、the_permalink()には必要ないのでしょうか。答えを先に言うと、the_permalink()には無害化が不要です。これは、the_permalink()は中でecho esc_url(get_permalink())というような処理を行っており、すでに無害化されているためです。

IDやクラスを割り振って、スタイルを調整しよう

必要な要素は揃いましたので、IDやクラス、Wrapper用の<div>などを記述して、スタイルを調整しましょう。

最終的なコードは次のようになりました。「自分で書くのが面倒!」という方は、丸ごとコピーしても動くはずです。

<?php get_header(); ?>

<div id="primary" class="l-main content-area">
  <main id="main" class="site-main" role="main">
    <?php if( have_posts() ) : ?>
      <div class="entry-list">
        <?php while( have_posts() ) : the_post(); ?>    
          <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <header class="entry-header">
              <time class="tiny-text entry-date"><?php echo get_the_date(); ?></time>
              <?php the_title( 
                '<h2 class="heading-big entry-title"><a href="' . esc_url( get_permalink() ) . '">',
                '</a></h2>'
              ); ?>     
            </header>

            <?php if( has_post_thumbnail() ) : ?>
              <div class="entry-thumbnail">
                <a href="<?php the_permalink(); ?>">
                  <?php the_post_thumbnail(); ?>
                </a>
              </div>
            <?php endif; ?>

            <div class="entry-content">
              <?php the_content( '<span class="btn btn-primary">Continue Reading</span>' ); ?>
            </div>
          </article> 
        <?php endwhile; ?>
      </div>
    <?php else: ?>
      <section class="no-result not-found">
        <header class="entry-header">
          <h1 class="heading-big entry-title">Nothing Found</h1>
        </header>

        <div class="entry-content">
          おさがしの記事は見つかりませんでした。 
        </div>
      </section>
    <?php endif; ?>
  </main>
</div>

<aside id="secondary" class="sidebar" role="complementary">
  サイドバー
</aside>

<?php get_footer(); ?>

説明していないコードがあるので、少し補足しておきます。

投稿に自動的にクラスを割り振る

8行目の記事を囲んでいる<article>タグは次のようになっています。

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

the_ID()は投稿のIDを出力する関数で、idを投稿のIDで一意に割り当てるようにしています。たとえば投稿のIDが100の場合、<article id="post-100">になります。

post_class()は投稿の種類に応じて自動でクラスをつけてくれる便利な関数です。たとえばpostcategory-photoなどのクラスがつきます。body_class()と似たような関数ですね(詳しくはこのライブラリを参考にしてください)。

アイキャッチ画像があるかどうかを判定する

17行目のhas_post_thumbnail()は、投稿にアイキャッチ画像があるかどうかを判定する関数です。仮にアイキャッチ画像がなかった場合、不要なタグが出力されるのを防ぐためにifによって判定しているわけですね。

これを利用すれば、たとえばアイキャッチ画像がなかった場合はデフォルトの画像を表示するといったことも可能になります。

<div class="entry-thumbnail">
  <a href="<?php the_permalink(); ?>">
    <?php if( has_post_thumbnail() ) : ?>
      <?php the_post_thumbnail(); ?>
    <?php else: ?>
      <img src="...">
    <?php endif; ?>
  </a>
</div>

記事がなかったときの表示

32行目から40行目は、記事が1件もなかったときに表示される内容です。記事が見つからないケースはまれですが、検索結果が見つからなかったときはこちらの分岐が使われますので、簡単でも実装しておきましょう。

記事が見つからなかったときの表示
記事が見つからなかったときの表示

ページネーションを実装しよう

記事が増えてくると、2ページ目や3ページ目にアクセスするためのリンクが必要になります。

ページネーション
ページネーション

現在のWordPressでは、ページネーションが非常に容易に実装できます。

<?php the_posts_pagination(); ?>

ページネーションを表示したい場所にこの1行を記載するだけです。簡単ですね! 関数の詳しい内容はこのライブラリを参照してください。

...(省略)...
        <div class="entry-content">
          <?php the_content( '<span class="btn btn-primary">Continue Reading</span>' ); ?>
        </div>
      </article> 
    <?php endwhile; ?>
  </div>

  <?php the_posts_pagination(); ?>
<?php else: ?>
...(省略)...

実践ではwhile文が終わったあたりに記載することになります。

なお、「1ページに表示する最大投稿数」は初期状態で10になっています。したがって記事が11以上ないとページネーションは表示されません。ダミーの記事をたくさん用意するのは大変ですので、テスト時には1ページの件数を2や3すると確認がしやすくなるでしょう。

この件数は、管理画面の[設定]にある[表示設定]から変更することができます。

1ページに表示する最大投稿数
1ページに表示する最大投稿数

サイドバーを実装しよう

サイドバーには、ウィジットと呼ばれる小さな部品を管理画面から登録することができます。たとえば最近の投稿一覧を表示したり、検索フォームを追加したりといったことが簡単に実現できます。

テーマでサイドバーを有効化しよう

サイドバーは登録しないと使えませんので、functions.phpに次のようなコードを追加します。

/*
 * Register sidebar
 */
function whitesnow_widgets_init() {
  // Register main sidebar
  register_sidebar( array(
    'name'          => 'Main Sidebar',
    'id'            => 'sidebar-main',
    'description'   => 'Add widgets you want to display in sidebar.',
    'before_widget' => '<section id="%1$s" class="widget %2$s">',
    'after_widget'  => '</section>',
    'before_title'  => '<h5 class="widget-title">',
    'after_title'   => '</h5>',
  ) );
}

add_action( 'widgets_init', 'whitesnow_widgets_init' );

register_sidebar()がサイドバーを登録するための関数です。なにやらたくさんの設定項目がありますが、そこまで難しくありませんので、下の表を参考に適宜設定してください。

'name'サイドバーの名前。好きにつけて構いません
'id'サイドバーのID。後で必要になります。小文字の半角英数字とハイフンで構成してください
'description'サイドバーの説明文。なくても構いません
'before_widget'ウィジットの前に表示する文字列。スタイルしやすいようdivなどで囲っておきましょう
'after_widget'ウィジットの後に表示する文字列。通常'before_widget'で開いたタグの閉じタグを入れます
'before_title'ウィジットのタイトルの前に表示する文字列。スタイルしやすいようhタグで囲っておきましょう。
'after_title'ウィジットのタイトルの後に表示する文字列。通常'before_title'で開いたタグの閉じタグを入れます

これで、テーマにサイドバーが登録されました。

サイドバーはいくつでも登録することができる

サイドバーはいくつでも登録することができます。たとえばトップページと個別ページでサイドバーの内容を変えたいときは、それぞれのサイドバーを登録します。「サイド」という名前がついていますが、別に横に配置する必要もありませんので、本文の下や、フッターにウィジットエリアとして作成する使用方法も十分考えられます。

ウィジットはつけ外しや追加が簡単なので、積極的に有効活用しましょう。

サイドバーにウィジットを登録しよう

ウィジットは、管理画面の[外観]にある[ウィジット]で登録することができます。

サイドバーにウィジットを登録
サイドバーにウィジットを登録

ウィジットを登録したら、タイトルなどの設定を行って保存しておきましょう。

ウィジットを編集
ウィジットを編集

サイドバーの詳しい説明はこの記事で行っていますので、参考にしてみてください。

sidebar.phpを編集して、サイドバーを表示しよう

ウィジットを登録し準備ができたので、今度はサイトにサイドバーを表示してみましょう。

sidebar.phpを編集する

sidebar.phpを開いて、次のようなコードを記載します。

<?php
/*
 * sidebar.php
*/

if ( ! is_active_sidebar( 'sidebar-main' ) ) {
  return;
}
?>

<aside id="secondary" class="sidebar" role="complementary">
  <?php dynamic_sidebar( 'sidebar-main' ); ?>
</aside>

サイドバーを表示する関数は、12行目のdynamic_sidebar()です。この関数の引数に、登録したサイドバーのidを渡してください。

6行目のis_active_sidebar()は、サイドバーが有効かどうかを調べるための関数です。今回は有効でない場合にreturnすることでその後の処理が実行されないようにしています。

サイドバーを表示したい場所でsidebar.phpを読み込む

sidebar.phpを読み込むには、get_sidebar()という関数を使用します。index.phpを開いて、この関数を呼んでみましょう。

<?php get_header(); ?>

<div id="primary" class="l-main content-area">
  <main id="main" class="site-main" role="main">
    <?php if( have_posts() ) : ?>
      ...(省略)...
    <?php endif; ?>
  </main>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

サイドバーはメインコンテンツの隣に表示するので、11行目のあたりに記載しました。

これでindex.phpは完成です! 念のため全コードを以下に記載しておきますね。

<?php
/*
 * index.php
 *
 * The main template file for white theme.
 * This is always used when there is no specific template like archive.php, category.php.
 *
 * @package WordPress
 * @subpackage WhiteShow
 * @since 1.0
 * @version 1.0
 */
?>

<?php get_header(); ?>

<div id="primary" class="l-main content-area">
  <main id="main" class="site-main" role="main">
    <?php if( have_posts() ) : ?>
      <div class="entry-list">
        <?php while( have_posts() ) : the_post(); ?>    
          <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <header class="entry-header">
              <time class="tiny-text entry-date"><?php echo get_the_date(); ?></time>
              <?php the_title( 
                '<h2 class="heading-big entry-title"><a href="' . esc_url( get_permalink() ) . '">',
                '</a></h2>'
              ); ?>     
            </header>

            <?php if( has_post_thumbnail() ) : ?>
              <div class="entry-thumbnail">
                <a href="<?php the_permalink(); ?>">
                  <?php the_post_thumbnail( 'post-thumbnail' ); ?>
                </a>
              </div>
            <?php endif; ?>

            <div class="entry-content">
              <?php the_content( '<span class="btn btn-primary">Continue Reading</span>' ); ?>
            </div>
          </article> 
        <?php endwhile; ?>
      </div>
      
      <?php
        the_posts_pagination( array(
          'screen_reader_text'  => '投稿のナビゲーション',
        ) );
      ?>
    <?php else: ?>
      <section class="no-result not-found">
        <header class="entry-header">
          <h1 class="heading-big entry-title">Nothing Found</h1>
        </header>

        <div class="entry-content">
          おさがしの記事は見つかりませんでした。 
        </div>
      </section>
    <?php endif; ?>
  </main>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

個別ページを作成しよう

トップページが完成したので、今度は記事を表示するための個別ページを作成します。

個別ページ
個別ページ

トップページとほとんど同じ構成ですので、index.phpから必要な部分をコピーすればあっという間に完成します。

index.phpからsingle.phpに必要な部分をコピーしよう

まず、新しくsingle.phpというファイルを作成し、テーマフォルダに保存してください(必ずindex.phpなどと同じ階層に保存します)。

次に、このsingle.phpに、index.phpからループを除いた部分をコピーしてきましょう。

<?php get_header(); ?>

<div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
    if文があった場所
  </main>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

次に、while文とその中身のみをコピーしてもってきます。single.phpが使われているということは「記事がない」というケースが100%あり得ないので、if文は必要ありません。

<div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
    <?php while( have_posts() ) : the_post(); ?>    
      <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <header class="entry-header">
          <time class="tiny-text entry-date"><?php echo get_the_date(); ?></time>
          <?php the_title( 
            '<h2 class="heading-big entry-title"><a href="' . esc_url( get_permalink() ) . '">',
            '</a></h2>'
          ); ?>     
        </header>

        <?php if( has_post_thumbnail() ) : ?>
          <div class="entry-thumbnail">
            <a href="<?php the_permalink(); ?>">
              <?php the_post_thumbnail(); ?>
            </a>
          </div>
        <?php endif; ?>

        <div class="entry-content">
          <?php the_content( '<span class="btn btn-primary">Continue Reading</span>' ); ?>
        </div>
      </article> 
    <?php endwhile; ?>
  </main>
</div>

これで大体完成です! 実際にサイトを開いて、投稿が表示されているかどうかを確認してみてください。

本来同じような処理はまとめたほうが良い

今回は簡単のため、コピーして使っていますが、本来は同じような処理が複数の場所にあるのは好ましくありません。WordPressでは’part’という機能が備わっているので、partにまとめて必要なところでget_template_part()を使って呼び出す方が無駄がなく、メンテナンス性が高くなります。

個別ページ用に調整を加えよう

個別ページには、記事へのリンクが必要ありませんので、これらの処理は取り除いてしまいましょう。また、記事のタイトルはh2ではなくh1のほうが良いでしょう。

<?php while( have_posts() ) : the_post(); ?>    
  <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
      <time class="tiny-text entry-date"><?php echo get_the_date(); ?></time>
      <?php the_title( '<h1 class="heading-big entry-title">', '</h1>' ); ?>     
    </header>

    <?php if( has_post_thumbnail() ) : ?>
      <div class="entry-thumbnail">
        <?php the_post_thumbnail(); ?>
      </div>
    <?php endif; ?>

    <div class="entry-content">
      <?php the_content(); ?>
    </div>
  </article> 
<?php endwhile; ?>

5行目のthe_title()、10行目のthe_post_thumbnail()およびthe_content()にあったリンクをすべて削除しました。the_content()は個別ページで使用すると「続きを読む」のリンクを表示せず、本文すべてを表示するよう作られていますので、そのままでも問題にはなりません。

前後の記事へのリンクを表示しよう

今度は、前後の記事へのリンクを表示したいと思います。

前後の記事へのリンク
前後の記事へのリンク

前後の記事へのリンクは、the_post_navigation()という関数で簡単に実装することができます。先ほど出てきたthe_posts_navigation()と混同しやすいので注意してください。post/postsと単数形と複数形の違いがあります。

...(省略)...
  <div class="entry-content">
    <?php the_content(); ?>
  </div>
</article> 

<?php the_post_navigation(); ?>
...(省略)...

デフォルトの設定では、次のように前後の記事のタイトルがリンクテキストとして使われます。

デフォルトの状態での前後の記事へのリンク
デフォルトの状態での前後の記事へのリンク

the_post_navigation()の第1引数に配列を渡すことで、これらのテキストを変更することができます。たとえばテキストを「前の記事」「次の記事」に変更するには、次のように記述します。

<?php 
  the_post_navigation( array(
    'prev_text' => '<span class="size-small">前の記事</span>',
    'next_text' => '<span class="size-small">次の記事</span>',
  ) ); 
?>

不要であればタグをつける必要はありません。この関数の詳しい内容はこちらを参照してください。

個別ページでは少し大きめのアイキャッチ画像を表示しよう

記事の一覧では小さめのアイキャッチ画像を、個別ページでは大きな画像を表示したいということはよくあります。先ほどアイキャッチ画像のサイズをset_post_thumbnail_size()を使って変更しましたが、これとは別に新たに画像のサイズを追加することができます

新しく画像のサイズを追加する

functions.phpを開いて、先ほどサムネイルのサイズを変更したあたりを修正します。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
  add_image_size( 'whitesnow-single-image', 960, 540, true );
} 

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );

add_image_size()は新しい画像のサイズを追加する関数で、第1引数にサイズの名前を、第2引数と第3引数に幅と高さを指定します。

画像を再生成する

サイズを追加するだけであれば関数を呼ぶだけで簡単に実現できるのですが、すでに登録されている画像については新しいサイズの画像は自動で生成されません。新しく画像をアップロードして登録しなおすか、またはプラグインを使って再生成する必要があります。今回はAJAX Thumbnail Rebuildというプラグインを使ってみます。

[プラグイン]→[新規追加]画面で、AJAX Thumbnail Rebuildを検索します(1)。

AJAX Thumbnail Rebuildを追加
AJAX Thumbnail Rebuildを追加

2の[今すぐインストール]をクリックし、インストールが完了したらそのまま[有効化]してください。

プラグインが有効化されたら、実際にサムネイルを再生成してみましょう。

サムネイルを再生成
サムネイルを再生成

1[ツール]から2[Rebuild Thumbnails]をクリックします。

すると、現在有効になっているサムネイルサイズの一覧が表示されますので、3先ほど登録したサムネイルにチェックを入れ、さらに4[アイキャッチ画像のみ再生成]にもチェックを入れます。

最後に5[サムネイルの再生成]をクリックすれば、サムネイルの再生成が始まります。

追加した新しいサイズのサムネイルを表示する

画像の準備が調いましたので、実際に表示してみましょう。single.phpでサムネイルを表示していた部分を書き換えます。

<?php if( has_post_thumbnail() ) : ?>
  <div class="entry-thumbnail">
    <a href="<?php the_permalink(); ?>">
      <?php the_post_thumbnail( 'whitesnow-single-image' ); ?>
    </a>
  </div>
<?php endif; ?>

4行目のthe_post_thumbnail()に、サイズの名前を渡します。この関数は引数に何も渡さないと自動的に'post-thumbnail'が使われますが、このようにサイズ名を明示的に渡すこともできます。

single.phpの全文

これで個別ページを表示するためのsingle.phpが完成しました。index.phpから必要な部分をコピーしてきたので、とても簡単に実装できましたね。以下、全文を記載しておきます。

<?php
/*
 * single.php
 *
 * The template for all sinlge posts.
 *
 * @package WordPress
 * @subpackage WhiteShow
 * @since 1.0
 * @version 1.0
 */
?>

<?php get_header(); ?>

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

    <?php while( have_posts() ) : the_post(); ?>    
      <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <header class="entry-header">
          <time class="size-tiny entry-date"><?php echo get_the_date(); ?></time>
          <?php the_title( '<h1 class="heading-big entry-title">', '</h1>' ); ?>     
        </header>

        <?php if( has_post_thumbnail() ) : ?>
          <div class="entry-thumbnail">
            <?php the_post_thumbnail( 'whitesnow-single-image' ); ?>
          </div>
        <?php endif; ?>

        <div class="entry-content">
          <?php the_content(); ?>
        </div>
      </article> 

      <?php 
        the_post_navigation( array(
          'prev_text'           => '<span class="size-small">前の記事</span>',
          'next_text'           => '<span class="size-small">次の記事</span>',
          'screen_reader_text'  => '前後の記事へのリンク',
        ) ); 
      ?>
    <?php endwhile; ?>

  </main>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

ナビゲーションを作ろう

ここまででブログに必要なほとんどの機能が完成しました。ここからは、ブログ以外のページ作成していきたいと思います。ただ、ページを作成してもメニューがないとアクセスできませんので、まずはナビゲーションメニューを作っていきましょう。

 

固定ページを追加しよう

最初に、固定ページを追加しておきます。管理画面の[固定ページ]から[新規追加]を選択して、タイトルと本文を入力してください。

固定ページを追加
固定ページを追加

完成したら、[公開]ボタンをクリックして保存しておきます。

 

テーマにメニューを登録しよう

メニューの機能を使用するには、テーマでメニューを登録しておく必要があります。functions.phpを開いて、アイキャッチ画像を有効化した関数を修正しましょう。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // Enable support for menus.
  register_nav_menu( 'header-navigation', 'Header navigation' );

  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
  add_image_size( 'whitesnow-single-image', 960, 540, true );
} 

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );

6行目のregister_nav_menu()がメニューを登録するための関数です。第1引数にメニューを表示する位置を(識別するための名前のようなもの)、第2引数に説明文を渡します。詳しくはこのライブラリを参照してください。

これでテーマでメニューが使えるようになりました。

メニューに項目を追加しよう

管理画面の[外観]から[メニュー]を選択します。

管理画面のメニュー
管理画面のメニュー

まだ1つもメニューを作成していませんが、WordPressが自動的にメニュー作成の準備をしてくれています。

新しいメニューを作成
新しいメニューを作成

1の[メニュー名]にメニューの名前を入力します。次に、左側の項目一覧から追加したいメニューにチェックを入れ、[メニューに追加]ボタンを押せば「メニュー構造」に登録することができます。ただ、今回は初めから必要なメニューが揃っていますので、特に何もしなくてよいでしょう。

それぞれのメニュー項目は、右側にある▼ボタンをクリックすることで編集できるようになります2。ここでは「ホーム」のナビゲーションラベルを「Home」に変えました。

最後に3のメニューの位置が先ほど追加した「Header navigation」になっていることを確認してから、4の[メニューを保存]をクリックします。

これで、「Header navigationというメニューの位置には、'main'というメニューを表示する」という設定が完了しました。

メニューの位置とメニュー

register_nav_menu()ではメニューの位置(メニューを入れる箱のようなもの)だけを登録します。この箱に何を入れるかは管理画面の[メニュー]で決めます。すこしだけわかりにくいですね。

メニューを表示しよう

最後に、実際にメニューを表示していきます。今回メニューはサイトの上部に表示しますので、header.phpを開いてください。

<header id="main-header" class="site-header">
  <div class="site-branding">
    <div class="site-logo">
      <a href="<?php echo esc_url( home_url( '/' ) ); ?>">
        <img src="<?php echo get_template_directory_uri(); ?>/images/logo.png">
      </a>
    </div>

    <div class="site-tagline">
      <?php bloginfo( 'description' ); ?>
    </div>
  </div>

  <nav id="main-navigation" class="site-navigation" role="navigation">
    <?php wp_nav_menu( array( 
      'theme_location'  => 'header-navigation',
      'menu_id'         => 'main-nav-top',
      'menu_class'      => 'main-nav',
    ) ); ?>
  </nav>
</header>

wp_nav_menu()は、「メニューの位置はここです」という宣言をするための関数です。配列でパラメータが3種類渡されていますが、それぞれ次のような意味です(この関数の詳しい内容は、このライブラリで解説しています)。

'theme_location'メニューの位置。先ほどregister_nav_menu()の第1引数で渡した値と同じにする
'menu_id'メニューが出力されるときにつけるid名
'menu_class'メニューが出力されるときにつけるクラス名

うまくいけば、ヘッダー部分にメニューが表示されているはずです。

メニューが追加された
メニューが追加された

これで固定ページの「About」に遷移できるようになりました!

固定ページ用のテンプレートを作成しよう

先ほどメニューを作成したので、固定ページにアクセスできるようになっています。何もしなくてもindex.phpがうまく機能し、ページが正しく表示されているはずですが、冗長な処理がありますし、せっかくなので固定ページ用のテンプレートも作成しておきましょう。

固定ページ
固定ページ

固定ページは個別ページと似ていますが、それよりもさらにシンプルで、日付・タイトル・本文の3つの要素しかありません。single.phpを少し調整すればよさそうですね。

固定ページ用のテンプレート、page.phpを作成しよう

固定ページ用のテンプレート、page.phpを作成し、テーマのフォルダに保存してください。single.phpと内容が似ているので、ファイル自体をコピーし、リネームしても構いません。

新規で作成した場合は、single.phpの内容を丸ごとコピーして持ってきます。

<?php get_header(); ?>

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

    <?php while( have_posts() ) : the_post(); ?>    
      <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <header class="entry-header">
          <time class="size-tiny entry-date"><?php echo get_the_date(); ?></time>
          <?php the_title( '<h1 class="heading-big entry-title">', '</h1>' ); ?>     
        </header>

        <?php if( has_post_thumbnail() ) : ?>
          <div class="entry-thumbnail">
            <?php the_post_thumbnail( 'whitesnow-single-image' ); ?>
          </div>
        <?php endif; ?>

        <div class="entry-content">
          <?php the_content(); ?>
        </div>
      </article> 

      <?php 
        the_post_navigation( array(
          'prev_text'           => '<span class="size-small">前の記事</span>',
          'next_text'           => '<span class="size-small">次の記事</span>',
          'screen_reader_text'  => '前後の記事へのリンク',
        ) ); 
      ?>
    <?php endwhile; ?>

  </main>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

さて、固定ページにはサムネイルは表示しませんし、前後の記事へのリンクも不要です。そこで、13~17行目と24~30行目を削除します。

<?php get_header(); ?>

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

    <?php while( have_posts() ) : the_post(); ?>    
      <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <header class="entry-header">
          <time class="size-tiny entry-date"><?php echo get_the_date(); ?></time>
          <?php the_title( '<h1 class="heading-big entry-title">', '</h1>' ); ?>     
        </header>

        <div class="entry-content">
          <?php the_content(); ?>
        </div>
      </article> 
    <?php endwhile; ?>

  </main>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

これでpage.phpは完成しました。とても簡単ですね!

固定ページのみスタイルを少し変えたい場合は、body_class()post_class()pageというクラスを割り当ててくれていますので、.page .entry-contentなどとすれば、固定ページ専用のスタイルを当てることができます。あるいは、固定ページではサイドバーが不要だったり、少しレイアウトを変えたかったりする場合でも、このpage.phpを編集すれば難なく実現することができます。

functions.phpを調整しよう

ここまでの実装でほとんどの機能は完成しましたが、もう少しだけやっておくことがあります。現在、functions.phpに書いてある内容は次の通りです。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // Enable support for menus.
  register_nav_menu( 'header-navigation', 'Header navigation' );

  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
  add_image_size( 'whitesnow-single-image', 960, 540, true );
} 

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );


/*
 * Enqueue styles and scripts.
 */
function whitesnow_enqueue_scripts() {
  // Load theme style.
  wp_enqueue_style( 'whitesnow-style', get_stylesheet_uri() );
}

add_action( 'wp_enqueue_scripts', 'whitesnow_enqueue_scripts' );


/*
 * Register sidebar
 */
function whitesnow_widgets_init() {
  // Register main sidebar
  register_sidebar( array(
    'name'          => 'Main Sidebar',
    'id'            => 'sidebar-main',
    'description'   => 'Add widgets you want to display in sidebar.',
    'before_widget' => '<section id="%1$s" class="widget %2$s">',
    'after_widget'  => '</section>',
    'before_title'  => '<h5 class="widget-title heading-small">',
    'after_title'   => '</h5>',
  ) );
}

add_action( 'widgets_init', 'whitesnow_widgets_init' );


/*
 * Remove #more-000 anchor from the read-more link.
 */
function whitesnow_remove_more_link_anchor( $link ) {
  $link = preg_replace( '/#more-[0-9]+/', '', $link );
  return $link;
}

add_filter( 'the_content_more_link', 'whitesnow_remove_more_link_anchor' );

タイトルタグを出力しよう

現在の状態だと、タイトルが表示されません。

タイトルが表示されていない
タイトルが表示されていない

これは<head>内にタイトルタグがないためです。ただし、だからと言ってheader.phpに直接書き込んだりはしません。functions.phpを開いて、タイトルタグが自動的に出力されるよう変更しましょう。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // WordPress will generate <title> tag automatically.
  add_theme_support( 'title-tag' );
  
  // Enable support for menus.
  register_nav_menu( 'header-navigation', 'Header navigation' );

  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
  add_image_size( 'whitesnow-single-image', 960, 540, true );
} 

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );

6行目のadd_theme_support( 'title-tag' )が、テーマでタイトルタグを有効にする関数です。これにより、各ページに応じて適切なタイトルが自動的に表示されるようになります。以下はその一例です。

トップページ“サイトの名前” - “キャッチフレーズ”
個別ページ・個別ページ“タイトル” - “サイトの名前”
カテゴリアーカイブページ“カテゴリ名” - “サイトの名前”

この内容は変えることができますが、ここでは説明を省略します。

コンテンツ幅を設定しよう

「コンテンツ幅」は、WordPressにコンテンツの最大幅を伝えるために設けられている機能です。たとえば投稿でYouTubeの動画を埋め込む際、コンテンツ幅を指定しておけばその幅で投稿されるようになるため、レイアウトが崩れてしまうのを防ぐことができます。

コンテンツ幅未設定
コンテンツ幅未設定

コンテンツ幅が設定してあると、下のように横幅を本文の幅と一致させることができます。

コンテンツ幅をブログの本文の幅と同じに設定
コンテンツ幅をブログの本文の幅と同じに設定

以下のように1行設定するだけですので、忘れずに記載しておきましょう。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // WordPress will generate <title> tag automatically.
  add_theme_support( 'title-tag' );

  // Enable support for menus.
  register_nav_menu( 'header-navigation', 'Header navigation' );

  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
  add_image_size( 'whitesnow-single-image', 960, 540, true );
  
  // Set the max content width.
  $GLOBALS['content_width'] = 704;
}

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );

フィードリンクを有効にしよう

ブログ用のテーマを想定していますので、フィードのリンクを有効にしておきましょう。

/*
 * Setup White Snow theme.
 */
function whitesnow_setup_theme() {
  // WordPress will generate <title> tag automatically.
  add_theme_support( 'title-tag' );

  // Enable support for adding RSS feed links to head.
  add_theme_support( 'automatic-feed-links' ); 

  // Enable support for menus.
  register_nav_menu( 'header-navigation', 'Header navigation' );

  // Enable support for Post Thumbnails.
  add_theme_support( 'post-thumbnails' );
  set_post_thumbnail_size( 760, 300, true );
  add_image_size( 'whitesnow-single-image', 960, 540, true );
  
  // Set the max content width
  $GLOBALS['content_width'] = 704;
}

add_action( 'after_setup_theme', 'whitesnow_setup_theme' );

これも、1行add_theme_support( 'automatic-feed-links' )と記載するだけです。ただし、このテーマにはコメントの機能が実装されていませんので、コメントフィードには意味がありません。

おわりに

とても長い記事になってしまいましたが、テーマの作成を最初から最後まで一通り解説してみました。いかがだったでしょうか。あまり凝ったデザインにせず、モバイル対応などを置いておけば1日程度でできてしまう内容です。ブログサイトを作るだけなら、意外に簡単にできてしまうものなんですね。検索やカテゴリーの機能、アーカイブもきちんと動作する、立派なブログサイトの完成です!

……とはいえ、実際にはもっとたくさんやった方がいいことがあります。たとえばコメントフォームを設置したり、カテゴリアーカイブではカテゴリ名を表示したり、あるいは検索結果のページでは何で検索して、何件見つかったかを表示したりなど、まだまだ細かい調整が残っています。

これらの詳しい説明は、また別の機会に行っていきたいと思います!

つづけて読む

この記事には続きがあります。

ぜひ合わせて読んでみてください!