WordPressでオリジナルのテーマを作成する際のフローをまとめました。サンプルも配布してるので、是非使ってみてください、
テーマ開発をやったことがない、それほどやってないという人でもなるべく分かるように書いていますので、手順通りにやっていただければ、テーマ開発をどうすれば良いのか?をわかってもらえると思います。
尚、執筆時点でのWordPressのバージョンは 4.8.2 です。
この記事を書くに当たり WordPress Codex日本語版と、WebDesign Recipes はじめてWordPressのオリジナルテーマを作るときの参考になればと思って書きました を参考にさせていただきました。
目次
- テーマのデザインをパーツに
- パーツの種類
- コーディング
- WordPressの環境構築
- 必要なファイル
- テンプレートの種類
- トップページのテンプレート化
- header.php の編集
- index.phpの編集 コンテンツ部分のWordPress化
- sidebar.phpの編集 ウィジェットを使ってサイドバーを実装する
- footer.php を編集する
- single.php の編集 個別投稿の表示
- page.php の編集 固定ページのテンプレート
- フィードの設定
- エスケープ処理
- functions.phpの役割
- テーマチェック
- テーマを翻訳対応する
- デバッグが終わったら
- ユニットテスト
- まとめ
- テーマの紹介
テーマのデザインをパーツに
最初からWordPressで作り出すのは慣れるまで難しいと思います。まず構造を考えるためにもデザインを作り、それをhtmlとCSSにしてからWordPressにしていきましょう。
WordPressはオープンソースのブログ/CMS プラットフォームです。今回はブログを作る事を目標に必要なものをデザインします。
index.png(トップページやアーカイブページで利用)
single.png(投稿ページで利用)
page.png(固定ページで利用)
パーツの種類
先程紹介したデザインをもとにパーツを説明していきます。
フロント・アーカイブページ
ブログのトップページやアーカイブページで利用します。アーカイブページとはカテゴリの記事一覧、タグの記事一覧、投稿者の記事一覧といった一覧ページの事です。トップページも記事全体のアーカイブとして表示するため、このデザインを利用します。
フロント・アーカイブページはこのような構成です
- ヘッダー(全ページ共通)
- 記事の一覧
- 記事タイトル
- 投稿日
- カテゴリ
- タグ
- アイキャッチ画像
- 抜粋
- 続きを読む
- サイドバー(全ページ共通)
- ページング
- フッター(全ページ共通)
投稿ページ
記事の詳細ページになります。WordPressの投稿画面にある投稿に入力されたデータを表示する時に使います。
詳細ページはこのような構成です
- ヘッダー(全ページ共通)
- コンテンツ部分
- 記事タイトル
- 投稿日
- カテゴリ
- タグ
- アイキャッチ画像
- 本文
- ページ分割のページング
- 投稿者情報
- コメント
- コメント一覧
- コメントのページング
- コメントフォーム
- サイドバー(全ページ共通)
- ページング
- フッター(全ページ共通)
固定ページ
今回のデザインであればaboutのみになっていますが、他にプライバシポリシーに関するページを作ったり、会社であれば、会社情報のページを作る時などに使います。固定ページはカテゴリやタグといったアーカイブに使うものが無く、階層を作ることは出来ますがアーカイブを作ることが出来ません。ブログの投稿とは違った、独立したページを作るのに向いています。
固定ページは下記のような構成となります。
- ヘッダー(全ページ共通)
- コンテンツ部分
- サイドバー(全ページ共通)
- フッター(全ページ共通)
コーディング
デザインの中で出てきたパーツをそれぞれ独立できるようにコーディングしていきます。
- ヘッダー(全ページ共通)
- コンテンツ
- 記事タイトル(全ページ共通)
- 投稿日(フロント・アーカイブと詳細)
- カテゴリ(フロント・アーカイブと詳細)
- タグ(フロント・アーカイブと詳細)
- アイキャッチ画像(全ページ共通)
- 抜粋文章(フロント・アーカイブ)
- 続きを読む(フロント・アーカイブ)
- 本文(詳細ページと固定ページ)
- ページ分割のページング
- 投稿者情報(詳細ページ)
- コメント(詳細ページ)
- コメント一覧
- コメントのページング
- コメント投稿
- ページング(フロント・アーカイブと詳細)
- サイドバー(全ページ共通)
- カテゴリ
- タグ
- アーカイブ
- フッター(全ページ共通)
これらのパーツの組み合わせでそれぞれのページを組み立てることを考えましょう。
全ページ共通のものは全てのページで同じパーツを使うので、index.htmlを作れば、single.html、page.htmlを作る時はコピーして持ってくるだけで良いということです。
保存する場所ですが、WordPressのテーマディレクトリに新たにディレクトリを作成し、そこに保存していきます。
ソースファイルのサンプルをダウンロードできるようにしています。下記よりご自由にお使いください。ライセンスはGPLです。
保存先はWordPressのテーマディレクトリに保存しましょう。その為にまずWordPressがローカルで動く環境を作ります。
WordPressの環境構築
MAMPなどですでにPHPが動く人は WordPress 日本語 からダウンロードして設置してください。
まだの人は Local by Flywheel をインストールすればテーマの開発にすぐ着手できるので、こちらをオススメします。
Local by Flywheelの使い方
- FREE DOWNLOAD よりダウンロードしてインストールします。
- LET’S GO のボタンをクリックするとインストールが始まるので、指示にしたがって進めればインストールはすぐに終わります。
- インストールが終われば早速環境を用意します。左下に + マークがあるのでクリックし、サイトの名前を入れてください。
- そのまま continue をクリックして進み、 ADD SITE ボタンをクリックすれば完了です。パスワード入力を求められたら、パソコンやMacを起動する際のパスワードを入れてください。
完了すると下記が立ち上がります。
- サイト名の下にあるファイル保存場所の矢印をクリックると Finder やエクスプローラー等 で表示されると思いますので
サイト名/app/public/wp-content/themes/
まで移動します。 - この場所がテーマの保存場所になるので、ここに新たにフォルダを作り、その中にコーディングデータを入れていきます。今回は解説するために
wpbeg
というディレクトリ名にしました。サイト名/app/public/wp-content/themes/wpbeg/
という構成になっていれば大丈夫です。
WordPressの言語はデフォルトで英語になっているので、日本語に変更しておきましょう。
上記の ADMIN をクリックし、管理画面にログインしてください。
Setting > General より Site Language の項目から日本語を選択して Save Changes をクリックして保存すれば言語が日本語に切り替わります。
環境が整ったら、wpbeg ディレクトリの中にファイルを作ってコーディングしていきます。
ダウンロードしたサンプル を利用する場合は、圧縮されたファイルを解凍後 wpbeg-static/ の中にあるファイルを WordPress のテーマディレクトリに作成した wpbegディレクトリ の中に入れます。
現状下記のようになっていると思います。
wpbeg/css/wpbeg.css
/images/
/index.html
/page.html
/single.html
必要なファイル
テーマを最低限機能させるのに必要なファイルは
- index.php
- style.css
の2つになります。これらがないとテーマとして認識されません。
ですので、まず
- index.html を index.php にリネームする
- style.cssを作成して必要な記述を行う
また、これらのファイルは開発するテーマディレクトリの直下に置く必要があるので注意してください。(例:themes/wpbeg/)
また、index.html 同様、single.html、page.htmlもリネームしておいてください。
- page.html → page.php
- single.html → single.php
style.cssに必要な記述
開発するテーマディレクトリ wpbeg の直下に 下記の情報をコメントとして記載して style.css という名前で保存してください
/*
Theme Name: WPBEG
Description: テーマ開発練習用テーマ
Version: 1.0.0
Theme URI: https://github.com/yat8823jp/wpbeg
Author: YAT
Author URI: https://wp.yat-net.net.com
Tags: right-sidebar, blog
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
Text Domain: wpbeg
*/
各項目の意味は以下のとおりです。
/*
Theme Name: //テーマの名前
Description: //テーマの説明
Version: //バージョン
Theme URI: //テーマの URL
Author: //作った人の名前
Author URI: //作った人の URL
Tags: //テーマのタイプ
License: //ライセンス(WordPressのテーマやプラグインを公開して配布する場合、ライセンスはGPLになります。)
License URI: //ライセンスの URL
Text Domain: //テキストドメイン(翻訳させたい箇所を指示する際に使います。テーマディレクトリ名を入れます。)
*/
ここまでで WordPress はテーマを認識してくれるようになります。
管理画面から 外観 > テーマを選択すると下記のようになっています。
他にも
必須ではありませんが、管理画面のテーマを選択箇所で現状だと画像が無いため、スクリーンショットが出ません。表示したい場合は、1200✕900ピクセルで画像を作り、 screenshot.png という名前で開発テーマディレクトリ wpbeg フォルダの直下に保存しておきます。( サンプル )
スクリーンショットを入れると下記のように画像が出ます。
また、ドキュメント用に readme.txt や、ファビコン なども用意しておくと良いです。
尚サンプルの場合、faviconは images/common/ico/favicon.ico に入っています。
ここまででディレクトリの構造は、以下のようになっているはずです。
wpbeg/css/wpbeg.css
/images/
/index.php
/page.php
/single.php
/screenshot.png
/style.css
テーマの有効化
では実際にテーマを有効化してみましょう。 WPBEG をロールオーバーすると有効化のボタンが出てくるので、クリックして有効にします。
サイトがどうなっているか確認するためサイトを表示します。
画面左上のサイトを表示をクリックするとフロント側(実際のページ)を見ることができます。
ページ自体は表示されますが、スタイルが当たっておらず、画像も表示されていませんし、リンクもhtmlのときのままです。
ここからWordPressがテーマとして正しく機能するようソースを変更していきます。
テンプレートの種類
テーマを作る際はコーディングしたデータをテンプレート化し、それぞれをパーツにして必要な箇所で呼び出して表示するようにしていきます。
index.php だけで作ることも可能ですが、ソースの管理がしづらくなるので、用途に合わせて適切なテンプレートファイルを利用したほうが良いです。
では、まず基本的なテンプレートファイルを紹介していきます。
style.css
前節で冒頭に必要な記述を施したスタイルシートです。この記述はテーマのヘッダ情報といい、WordPress がテーマを認識する為に使われます。
rtl.css
言語によってはテキストを右から左へ記述するものが有り、その場合はこのスタイルシートが自動的に呼び出されます。
index.php
今回の記事ではトップ及びアーカイブという説明をしていましたが、このファイルはメインのテンプレートであり、これから説明していくテンプレートがない場合はこのファイルが呼び出されます。
今回はこのファイルとsingle.php、page.phpしか用意しないため、他のテンプレートが呼び出される場合は、この index.php が呼び出されるということになります。
comments.php
コメント部分を表示するためのテンプレートです。
デザイン上にあるコメント一覧と、コメント投稿の部分をこのファイルに記述し、single.php で読み込みこみます。
front-page.php
フロントページ用のテンプレートです。静的なWebサイトを表示する場合 index.html がフロントページとなりますが、WordPress でフロントページを作る場合はこの front-page.php を使うか、次に説明する home.php を使うことになります。尚、両方のファイルが存在する場合は front-page.php が優先されます。
home.php
ホームページ用テンプレートです。管理画面にある 設定 > 表示設定 の最新の投稿を表示する為のテンプレートになります。
尚、表示を固定ページに変更した場合は、指定した固定ページがフロントページになります。
single.php
投稿を表示するためのテンプレートです。今回使うテンプレートファイルになります。
single-.php
カスタム投稿タイプの投稿を表示するためのテンプレートファイルです。WordPressには投稿が用意されていますが、それとは別に新たな投稿を作ることができます。その場合呼ばれるのはこのテンプレートファイルになり、例えば books というカスタム投稿タイプの投稿を表示するには、 single-books.php を用意して表示します。
page.php
固定ページを表示する為のテンプレートファイルです。こちらも今回利用するテンプレートになります。
category.php
カテゴリを表示するためのテンプレートファイルです。
tag.php
タグを表示するためのテンプレートファイルです。
taxonomy.php
タクソノミーを表示するためのテンプレートです。タクソノミーとは分類の事で、デフォルトであれば「カテゴリ」と「タグ」がタクソノミーとなります。またこのタクソノミーは新たに追加することができ、そちらはカスタムタクソノミーと呼ばれます。
author.php
投稿の制作者を表示するためのテンプレートです。WordPress 内で登録したユーザー情報を呼び出して表示する際に使います。
date.php
日付ベースで表示したい場合に利用するテンプレートです。今回のデザインだとサイドバーにある Archive のそれぞれ内容を表示する場合に利用します。
archive.php
アーカイブ表示用のテンプレートです。カテゴリや作者、日付といったアーカイブ情報を表示する際に利用し。category.php、author.php、date.php が存在する場合は、それらのテンプレートが優先されます。
search.php
検索結果を表示するためのテンプレートです。
attachment.php
添付ファイル用のテンプレートです。特定の添付ファイルを表示する場合に利用します。
image.php
添付画像用のテンプレートです。特定の添付画像を表示する場合に利用し、このテンプレートが存在しない場合は、attachment.php が呼び出されます。
404.php
404 Not Found テンプレートです。ユーザーから要求された内容が存在しない場合にこのテンプレートが呼ばれます。
header.php
ヘッダー部分をパーツとして作る際に利用するテンプレートファイルです。
footer.php
フッター部分をパーツとして作る際に利用するテンプレートファイルです。
sidebar.php
サイドバー部分をパーツとして作る際に利用するテンプレートファイルです。
searchform.php
検索フォームを表示するためのテンプレートファイルです。
その他
他にテンプレートファイルは存在しますが、今回は差し当たってテーマを作る際に最低限必要なものを紹介しました。
では、実際にコーディングしたデータをテンプレート化していきましょう。
改めてトップページのパーツを確認しましょう。
トップページのテンプレート化
ヘッダー部分
index.phpを編集してヘッダーのソース部分を抜き出します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
中略
<div class="menu-gmenu-container">
<ul class="menu">
<li class="menu-item current_page_item"><a href="index.html">Blog</a></li>
<li class="menu-item"><a href="page.html">About</a></li>
</ul>
</div>
</header>
冒頭から </header>
までを切り取り、エディターに貼り付けて header.php という名前で テーマディレクトリの wpbeg 直下へ保存してください。
index.php
からヘッダー部分がなくなってしまったので、なくなってしまった箇所に <?php get_header(); ?>
と記述します。
<?php get_header(); ?> //header.phpを読み込むテンプレートタグ(インクルードタグ)
get_header() はテンプレートタグといい、WordPressに備わっている機能を呼び出したり、データを取得する時に使うものです。
今回は header.php を呼び出す必要があったので、このテンプレートタグを使ってヘッダーを読み込むようにしています。
テンプレートタグは非常に沢山存在しているので、全てを紹介する事が難しいため、詳しく知りたい方は Codex を読んでみてください。本記事では必要なテンプレートタグのみを必要な箇所で解説しながら進めていきます。
フッター部分
ヘッダーと同様にフッター部分を抜き出します。
<footer class="footer">
<p class="footer__copyright"><small>© WPBEG 2017</small></p>
</footer>
</body>
</html>
こちらは footer.php として保存し、index.php には <?php get_footer(); ?>
と記述して、フッターを読み込みます。
<?php get_footer(); ?> //footer.phpを読み込むテンプレートタグ(インクルードタグ)
サイドバー部分
ヘッダー、フッター同様にこちらもサイドバーの部分を抜き出します。
<div class="p-sidebar">
<div class="widget">
<h2><i class="fa fa-folder-open" aria-hidden="true"></i> Category</h2>
<ul>
<li><a href="#">カテゴリ名</a></li>
<li><a href="#">カテゴリ名</a></li>
</ul>
</div>
<div class="widget">
<h2><i class="fa fa-tags" aria-hidden="true"></i> Tag</h2>
<div class="tagcloud">
<a class="tag-cloud-link" href="#">タグ</a>
<a class="tag-cloud-link" href="#">タグ</a></div>
</div>
<div class="widget">
<h2><i class="fa fa-archive" aria-hidden="true"></i> Archive</h2>
<ul>
<li><a href="#">2017年10月</a></li>
<li><a href="#">2017年9月</a></li>
</ul>
</div>
</div>
こちらは sidebar.php として保存し、index.php では <?php get_sidebar(); ?>
と記述してサイドバーを読み込みます
<?php get_sidebar(); ?> //siderbar.phpを読み込むテンプレートタグ(インクルードタグ)
ここまででテーマディレクトリの中は下記のようになっていると思います。
wpbeg/css/wpbeg.css
/footer.php
/header.php
/images/
/index.php
/page.php
/screenshot.png
/sidebar.php
/single.php
/style.css
ここまでで編集したのは
- ヘッダーの分割( header.php の作成 )
- フッターの分割( footer.php の作成 )
- サイドバーの分割 ( sidebar.php の作成 )
- index.php 内にテンプレートタグの記述
header.php の編集
サイトの基本情報編集
このままではファイルを分割しているだけなので、もっとWordPressの機能を使って出力の仕方を変えてえていきましょう。
- サイトの名前を取得して表示
- サイトの情報を取得して表示
- トップページのURLを取得して表示
現状はソースファイルに直接記述してそれぞれを表示していますが、これを変えてみます。
<h1 class="header__ttl">
<a href="./">WPBEG<span class="header__ttl__sub">static</span></a>
</h1>
<p class="header__description">Just another WordPress site</p>
を
<h1 class="header__ttl">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?><span class="header__ttl__sub">static</span></a>
</h1>
<p class="header__description"><?php bloginfo( 'description' ); ?></p>
に書き換えます。
bloginfo( 'name') //管理画面の設定 > 一般 にある「サイトのタイトル」を取得して表示
home_url( '/' ); //現在のブログのホームURLを取得します。そのままですると '/' (スラッシュ)が付かないで、 `/` を付けて出力しています。
bloginfo( 'description' ); //管理画面の設定 > 一般 にある「キャッチフレーズ」を取得して表示
bloginfo( ‘name )、bloginfo( ‘description’ ) を利用することで、管理画面の下記から変更ができるようになりました。
bloginfo() で取得して表示できる情報は他にも色々あります。詳しくは Codex: テンプレートタグ/bloginfo を見てみてください。
home_url に関しては bloginfo と違い出力を機能として持っていません。その為 echo を使って取得したデータを出力しています。
また、esc_url という記述がありますが、これはエスケープ処理を施すための関数で詳しくは後ほど説明します。
またページごとに自動的にタグが追加されるよう bodyタグ に <?php body_class(); ?>
を付けておきます。
ページによって装飾を変えたい時などテンプレートに自分でクラスを付けなくてもWordPressが付けてくれるので便利です。
検索フォーム
現状だと静的なサイトの状態なので検索機能が使えません。WordPressはデフォルトで検索機能を持っているのでそれを利用します。
<form class="p-search-form" id="searchform">
<input class="p-search-form__keyword" placeholder="キーワード">
<input class="p-search-form__submit" id="searchsubmit" type="submit" value="検索">
</form>
検索部分を抜き出しました。
このソースを編集します。
searchform.php
<form class="p-search-form" id="searchform" method="get" action="<?php echo home_url('/'); ?>">
<input class="p-search-form__keyword" placeholder="キーワード" name="s" id="s">
<input class="p-search-form__submit" id="searchsubmit" type="submit" value="検索">
</form>
formに method="get"
action="<!?php echo home_url('/'); ?>"
を指定し、キーワードを入力するinputに name="s"
id="s"
を指定します。
WordPressの検索は s というパラメータで渡されるのでこの状態になります。
そして、編集が終わったら検索部分もテンプレート化しましょう。
ファイル名は searchform.php とし、 header.php の箇所は <?php get_search_form(); ?>
とします。
<form class="p-search-form" id="searchform" method="get" action="<?php echo home_url('/'); ?>">
<input class="p-search-form__keyword" placeholder="キーワード" name="s" id="s">
<input class="p-search-form__submit" id="searchsubmit" type="submit" value="検索">
</form>
ナビゲーション
次はヘッダーのナビゲーション部分を編集します。ここはこれまでとは違い、ソースを分離するだけでは無いので注意してください。
まずページナビのソースですが、現在はこうなっています。
<div class="menu-gmenu-container"> <ul class="menu"> <li class="menu-item current_page_item"><a href="index.html">Blog</a></li> <li class="menu-item"><a href="page.html">About</a></li> </ul> </div>
これを
<?php wp_nav_menu(); ?>
に書き換えます。
そして、WordPressの管理画面から、固定ページで About を作成します。
管理画面の固定ページ > 新規作成 を選び、タイトルに About を入力して公開をクリックで固定ページができあがります。
固定ページ一覧をクリックすると、現在登録されている固定ページを確認することが出来ます。
今作った About とサンプルとして登録されている Sample Page の2つが存在しており、フロント側を確認すると
という風に、固定ページに登録されているものが出現しています。
サンプルでは Blog と About を表示していますので、これを正しく出力されるよう設定を変える必要があります。
現時点ではメニューの設定は変更できないため、メニューのカスタマイズができるようWordPressに機能を追加します。
機能の追加についてはプラグインを導入する方法がありますが、今回はテーマ側で機能をもたせてみましょう。
テーマに機能を持たせるには functions.php というファイルを作成し、そこに必要なものを記述することで使えるようになります。
早速テーマディレクトリ wpbeg の直下に functions.php というファイルを作成し、下記ソースを貼り付けてください。
<?php add_theme_support( 'menus' );
これは、テーマにメニューという項目を機能をサポートすることを許可するという記述になります。
管理画面の外観を選択すると、さっきまではなかったメニューが追加されています。
最初は何もないので、新たに作成します。
メニュー名に gmenu という名前を入力し、メニュー作成をクリックしてください。
それができたら、左側にあるメニューから 固定ページ > 全て表示 を開き、ホームと About を選択し、メニューに追加をクリックします。
すると、選択した項目が右側に出現するので、ホームとなっている方のボタンの右側にある下矢印をクリックしナビゲーションラベルのホームをBlogに変更して保存します。
ちなみに順番を並び替えたいときはドラッグで順番を変えることが出来ます。
これで表示したいメニューが出来ました。フロント側を確認すると
となっているはずです。
これで、新たにメニューを追加したい時は管理画面からいつでも追加することができます。
現在 wpbeg の中身は以下となっています。
wpbeg/css/wpbeg.css /footer.php /functions.php /header.php /images/ /index.php /page.php /screenshot.png /searchform.php /sidebar.php /single.php /style.css
head部分
<body> と <header> 部分が出来たので、次は <head></head> の内部を作っていきます。
<head> 内に必ず入れないといけないコードを挿入します。
<?php wp_head(); ?>
// WordPressのテーマに含める関数。admin_barや必要となるソースの出力などを行う。
これがないとプラグインが機能しなかったり、出力したい情報が出力できなかったりします。忘れないよう必ずソースに含めてください。
場所は </head> の前になります。
では、ソースの修正をしていきましょう
<html lang="ja"> 中略 <title>index | wpbeg-static</title> 中略 <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/earlyaccess/mplus1p.css"> <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Sacramento&amp;subset=latin-ext"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="css/normalize.css"> <link rel="stylesheet" href="css/wpbeg.css"> <link rel="shortcut icon" href="//wp.yat-net.com/wpbeg-static/images/common/ico/favicon.ico">
このあたりを修正します
<html lang="<?php language_attributes(); ?>"> //言語設定を自動的に出力します 中略 <title>index | wpbeg-static</title> //削除 中略 <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/earlyaccess/mplus1p.css"> //削除 <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Sacramento&amp;subset=latin-ext"> //削除 <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> //削除 <link rel="stylesheet" href="css/normalize.css"> //削除 <link rel="stylesheet" href="css/wpbeg.css"> //削除 <link rel="shortcut icon" href="<?php echo get_template_directory_uri(); ?>/images/common/ico/favicon.ico">
CSS や JavaScript などは header で直接読み込むではなく functions.php に設定を書いて出力します。タイトルタグも同様にしてみましょう。
<?php //テーマサポート add_theme_support( 'menus' ); add_theme_support( 'title-tag' ); //タイトル出力 function wpbeg_title( $title ) { if ( is_front_page() && is_home() ) { //トップページなら $title = get_bloginfo( 'name', 'display' ); } elseif ( is_singular() ) { //シングルページなら $title = single_post_title( '', false ); } return $title; } add_filter( 'pre_get_document_title', 'wpbeg_title' ); function wpbeg_script() { wp_enqueue_style( 'mplus1p', '//fonts.googleapis.com/earlyaccess/mplus1p.css', array() ); wp_enqueue_style( 'Sacramento', '//fonts.googleapis.com/css?family=Sacramento&amp;subset=latin-ext', array() ); wp_enqueue_style( 'font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), '4.7.0' ); wp_enqueue_style( 'normalize', get_template_directory_uri() . '/css/normalize.css', array(), '4.5.0' ); wp_enqueue_style( 'wpbeg', get_template_directory_uri() . '/css/wpbeg.css', array(), '1.0.0' ); wp_enqueue_style( 'style', get_template_directory_uri() . '/style.css', array(), '1.0.0' ); } add_action( 'wp_enqueue_scripts', 'wpbeg_script' );
functions.php が少し長くなりましたが順に沿って解説します。
テーマサポート
先程メニューのカスタマイズで記載したものと似た記述で
add_theme_support( ‘title-tag’ );
を追記しました。これはタイトルタグのサポートを許可するという記述です。
その下の
functions.php //タイトル出力 function wpbeg_title( $title ) { if ( is_front_page() && is_home() ) { //トップページなら $title = get_bloginfo( 'name', 'display' ); } elseif ( is_singular() ) { //シングルページなら $title = single_post_title( '', false ); } return $title; } add_filter( 'pre_get_document_title', 'wpbeg_title' );
が実際の出力になります。
is_front_page() //投稿・固定ページにかかわらず、サイトのフロントページが表示されているかを判定する is_home() //メインブログページが表示されているかを判定する。 is_singular() //個別投稿のページかを判定する。is_single()、is_page() 、is_attachment() のいずれかに該当する場合に真を返す。
は条件分岐タグというもので、今表示されているページによって出力を切り替える時に使います。
この条件分岐は 関数にしておき、add_filter という関数を使ってWordPressがページを構成する際に自分が作った関数を通してページを出力させます。
ちょっとややこしいですが、WordPressにはフィルターやフックと言ったものが多数用意されており、これを利用することでページの表示にカスタマイズを行うことができる様になっています。
通常であれば、header.php から title タグを削除したので何も出力されないはずですが、このフィルターを通して処理を行うことで、<head></head> の部分が出力されるタイミングに合わせてタイトルタグも出力されるようになります。
functions.php function wpbeg_script() { wp_enqueue_style( 'mplus1p', '//fonts.googleapis.com/earlyaccess/mplus1p.css', array() ); wp_enqueue_style( 'Sacramento', '//fonts.googleapis.com/css?family=Sacramento&amp;subset=latin-ext', array() ); wp_enqueue_style( 'font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), '4.7.0' ); wp_enqueue_style( 'normalize', get_template_directory_uri() . '/css/normalize.css', array(), '4.5.0' ); wp_enqueue_style( 'style', get_template_directory_uri() . '/css/wpbeg.css', array(), '1.0.0' ); wp_enqueue_style( 'style', get_template_directory_uri() . '/style.css', array(), '1.0.0' ); } add_action( 'wp_enqueue_scripts', 'wpbeg_script' );
こちらもタイトルタグの出力同様、関数になっており、ここではスタイルシートを読み込むタグを出力しています。
今回のサンプルでは JavaScriptを利用していませんが、スクリプトについてもこの関数に wp_enqueue_script という関数を使って読み込ませます。
Codex: 関数リファレンス/wp_enqueue_script
削除する項目は functions.php に移りました。残りは <head></head> に残した箇所の修正です。
WordPressは相対パスで記述しても画像を表示することができないので、WordPressを経由してURLを出力するようにします。
get_template_directory_uri() //テーマディレクトリのURIを取得します。
このテンプレートタグを挿入することでWordPressがテーマディレクトリまでのURI情報を取得してくれるので、echo して出力すれば、テーマディレクトリの中に保存しているデータを出力することができます。
headerまとめ
ここまでで header.php の処理は終了です。
ソースコードをチェックしてみましょう
header.php <!DOCTYPE html> <html lang="<?php language_attributes(); ?>"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="format-detection" content="telephone=no"> <meta name="description" content="WordPress theme development static data for beginners"> <meta name="keywords" content="WordPress, Theme, development"> <link rel="shortcut icon" href="<?php echo get_template_directory_uri(); ?>/images/common/ico/favicon.ico"> <?php wp_head(); ?> </head> <body <?php body_class(); ?>> <header class="header"> <h1 class="header__ttl"><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?><span class="header__ttl__sub">static</span></a></h1>
<p class="header__description"><?php bloginfo( 'description' ); ?></p>
<?php get_search_form(); ?>
<?php wp_nav_menu(); ?>
</header>
functions.php <?php //テーマサポート add_theme_support( 'menus' ); add_theme_support( 'title-tag' ); //タイトル出力 function wpbeg_title( $title ) { if ( is_front_page() && is_home() ) { //トップページなら $title = get_bloginfo( 'name', 'display' ); } elseif ( is_singular() ) { //シングルページなら $title = single_post_title( '', false ); } return $title; } add_filter( 'pre_get_document_title', 'wpbeg_title' ); function wpbeg_script() { wp_enqueue_style( 'mplus1p', '//fonts.googleapis.com/earlyaccess/mplus1p.css', array() ); wp_enqueue_style( 'Sacramento', '//fonts.googleapis.com/css?family=Sacramento&amp;subset=latin-ext', array() ); wp_enqueue_style( 'font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), '4.7.0' ); wp_enqueue_style( 'normalize', get_template_directory_uri() . '/css/normalize.css', array(), '4.5.0' ); wp_enqueue_style( 'wpbeg', get_template_directory_uri() . '/css/wpbeg.css', array(), '1.0.0' ); wp_enqueue_style( 'style', get_template_directory_uri() . '/style.css', array(), '1.0.0' ); } add_action( 'wp_enqueue_scripts', 'wpbeg_script' );
そしてフロント側はこうなっていると思います。
header.php の編集のポイントとしては
- 管理画面で変更できるようになるべくWordPressのテンプレートタグを利用する
- 検索フォームはテンプレート化しておく
- テーマに機能を持たせるには
functions.php
を用意する - ナビゲーションは管理画面でカスタマイズし、それを読み込むようにする
- スタイルシートやスクリプトの読み込みは
wp_enqueue_style
もしくはwp_enqueue_script
を利用する - ページよって出力が変わるタイトルなどは、条件分岐タグを利用する
- wp_head() を忘れずに記述する
index.phpの編集 コンテンツ部分のWordPress化
次はコンテンツ部分をパーツにしていきます。
index.php、page.php、single.php は構成が少しづつ違いますがそれぞれをまとめて条件分岐で出力するもの・しないものを切り分けていきます。
少し分かりづらいですが、まず出力したいものをまとめてみましょう
- 記事タイトル – 全ページ共通
- 日付 – index.php、single.php
- 所属カテゴリ – index.php、single.php
- 所属タグ – index.php、single.php
- アイキャッチ画像 – 全ページ共通
- 抜粋文章 – index.phpのみ
- 続きを読む – index.phpのみ
- 本文 – page.php、single.php
あとは indesx.php でこれをリピートして表示です。
WordPressで投稿データを取得して表示するには、まずこのリピート部分にあたるループ処理というのが欠かせません。
ですので、まずはじめにループ処理を加えていきます。
その前準備として、WordPressにデータを入力しておきましょう。
- 管理画面の 投稿 > 新規作成を選択。
- タイトルを入力
- 抜粋に当たる冒頭の文章を入力 ※
- 続きを読むタグを挿入
- 本文を入力
- カテゴリーを登録してチェック
- タグを入力して追加
- 公開ボタンをクリック
※ 抜粋は Gutengerg だとブロック作成>レイアウト要素>続きを読むになります
この状態だとアイキャッチ画像が無いので、アイキャッチ画像を扱えるように functions.php に記述します。
functions.php add_theme_support( 'menus' ); add_theme_support( 'title-tag' ); add_theme_support( 'post-thumbnails' ); //新たに追加
ブラウザを更新すると
アイキャッチ画像の項目が出現するので、ここからアイキャッチ画像を設定します。
設定すると
投稿情報の右下に設定した画像が表示されるので、確認できたら更新をクリックします。
同じように投稿複数登録しておきましょう。
登録ができたら実際にループ処理を作っていきます、
ループ処理の作成
記事の投稿で登録されたものから出力するものは以下となります
- 記事タイトル – 投稿のタイトル
- 日付 – 投稿を保存すると自動的に保存される
- 所属カテゴリ – 投稿で登録したカテゴリ
- 所属タグ – 投稿で登録したタグ
- アイキャッチ画像 – 投稿で登録したアイキャッチ画像
- 抜粋文章 – 本文登録時に挿入した「続きを読む」までの文章
- 続きを読む – 本文登録時に挿入した「続きを読む」のタグ部分
- 本文 – 投稿で登録した本文
これを index.php では記事の数だけ出力の処理を繰り返して表示します。
index.php <?php if( have_posts() ) : //1.投稿データがあるかの条件分岐。 while( have_posts() ) : // 2.表示する投稿データがあれば繰り返し処理開始 the_post(); //3.ループ処理に必要なカウント処理等 4.「ここに出力したい処理などを記述」 endwhile; // 5.繰り返し処理ここまで。投稿データがまだあればwhileに戻る。なければ終了 else : //6.投稿データがなければ ?><p>表示する記事がありません</p><?php //7.ない時の処理 endif; ?> //8.条件分岐終了 ?>
これがループ処理のプログラムになります。プログラムを書いたことがないと何がどういう意味なのか分かりづらいと思いますが、簡単に解説すると
- if を使うことで、投稿データがそもそも存在するかを判定しています。ある場合は while文 に進み、無い場合は 2. 3. 4. 5. を飛ばして 6.の else まで処理が飛びます。
- 投稿データが一つでもあれば投稿データを表示するためのループ処理に入ります。 have_posts は次の投稿データを調べるための関数です。プログラムおいて処理の一番最初は 0 から始まります。そのため、1件目を習得するというのは、0の次の投稿データにあたる1番目が存在するか?を調べ、存在すればループ処理を実行するという流れになります。
- the_post は 2. で次の投稿データが存在した場合に実行される箇所で、この関数で実際に次の投稿データを習得する役割を持っています。この処理が入っていないと、次の処理を取得という処理がなされないため、意図しない動きとなってしまいます。
- この箇所に取得した情報を出力する処理を記述します。
- 繰り返し処理の終了を知らせる部分です。 have_post に戻った時次の投稿データがなければ条件を満たさないのでループ処理が完了となります。
ループ処理が出来上がったので、4.「ここに出力したい処理などを記述」を記述していきます。
サンプルでループ表示させる単体部分のソースは以下となります。
index.php <div class="post"> <h2 class="post__ttl"><a href="single.html">記事タイトル</a></h2> <ul class="post__meta"> <li class="post__meta__item"> <date class="post__meta__date">2017年10月31日</date> </li> <li class="post__meta__item"><i class="fa fa-folder" aria-hidden="true"><a class="post__meta__link" href="#">カテゴリ名</a></i></li> <li class="post__meta__item"><i class="fa fa-tag" aria-hidden="true"><a class="post__meta__link" href="#">タグ名</a></i></li> </ul> <img class="post__eyecatch" src="images/eyecatch/001.png" alt="アイキャッチ"> <p>本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。本文の抜粋が入ります。</p><a class="post__morelink" href="single.html">続きを読む</a> </div>
これをループ処理内部に入れ、テンプレートタグを当てはめると以下になります。
index.php <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="post__ttl"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <ul class="post__meta"> <li class="post__meta__item"> <date class="post__meta__date"><?php echo get_the_date(); ?></date> </li> <li class="post__meta__item"><i class="fa fa-folder" aria-hidden="true"><?php the_category( ', ' ); ?></i></li> <li class="post__meta__item"><i class="fa fa-tag" aria-hidden="true"><?php the_tags( '' ); ?></i></li> </ul> <?php the_post_thumbnail(); ?> <?php the_content( '続きを読む' ); ?> </div> <?php endwhile; else : ?><p>表示する記事がありません</p><?php endif;
?>
改変した箇所をピックアップすると
- 投稿IDの取得表示・・・Codex: テンプレートタグthe_ID
- 投稿のclassを取得表示・・・Codex: テンプレートタグ/post_class
- 投稿のURLを取得表示・・・Codex: テンプレートタグ/the_permalink
- 投稿のタイトルを取得表示・・・Codex: テンプレートタグ/the_title
- 投稿した時間を取得表示・・・Codex: テンプレートタグ/get_the_date
- 投稿の所属カテゴリを取得表示・・・Codex: テンプレートタグ/the_category
- 投稿の所属タグを取得表示・・・Codex: テンプレートタグ/the_tags
- 投稿のアイキャッチ画像を取得表示・・・Codex: テンプレートタグ/the_post_thumbnail
- 投稿の本文抜粋部分を取得表示・・・Codex: テンプレートタグ/the_content
これでコンテンツ部分の出力ができるようになったので、元々のソースは削除してしまいます。
各テンプレートタグに関して
出てきたタグに関して解説していきます。
the_ID は投稿に対するIDを取得しています。サンプルのソースではidを指定していませんでしたが、WordPressの場合投稿ごとにIDが発行されるので、WordPressの実装時には付けてみました。特定の記事に処理を入れたい場合などに利用できたりするので、このテンプレートタグは覚えておくといいと思います。 ループの中でのみ利用可能
post_class はページよってWordPressが自動的にclassを付与してくれます。生成するページによって付与されるクラスが変わるので、ページによってスタイルを変えたり、JavaScriptで制御を変えたりする場合に利用できるので、利用頻度は高くなると思います。
the_permalink 投稿のパーマリンクURLを取得します。パーマリンクというのはWordPressが吐き出すURLのことに当たりますが、URLの構造は管理画面から変更することが可能です。 ループの中でのみ利用可能
管理画面 > 設定 >パーマリンク設定 より、カスタマイズが可能になります。
ただ、サイトの運用が始まってからここを変えてしまうと、外部からリンクを貼ってくれているサイトからはリンクが繋がらなくなってしまうので、サイトの構築の段階でどうするかを決めて最初に設定するようにしましょう。
the_title 投稿のタイトルを取得するテンプレートタグです。 ループの中でのみ利用可能
get_the_date 現在の投稿が書かれた日付を取得します。出力する機能は無いため、出力する場合は echo する必要があります。出力を持ったテンプレートタグに the_date() がありますが、こちらは同じ日に書かれた投稿がある場合、最初の投稿に対してしか出力が行なえません。投稿日のアーカイブを作る場合はこちらのほうが使いやすいですが、全投稿で投稿日を出力する場合は今回のようなやり方になります。
尚、日付のフォーマットは管理画面から変更が可能です。
設定 > 一般 >日付のフォーマット
the_category 現在の投稿が所属するカテゴリリンクを取得し表示します。デフォルトだと ul タグを利用したフォーマットに沿って出力されてしまうので、今回は(‘, ‘)とすることで、フォーマットなしの状態で出力しています。 ループの中でのみ利用可能
the_tags 現在の投稿が所属するタグリンクを取得して表示します。デフォルトだと先頭に タグ という文字列がはいってしまうので、今回は( ” )とすることで先頭の文字列が出ないようにしています。 ループの中でのみ利用可能
the_post_thumbnail 投稿に紐付いているアイキャッチ画像を取得し、表示します。 ループの中でのみ利用可能
the_content 投稿の本文を取得して表示します。index.php のようなアーカイブページであれば、「続きを読む」タグで挿入した more タグまでの文章を表示し、( ‘続きを読む’ ) で指定したリンクテキストを出力します。投稿を表示する single.php などであれば全文が表示されます。 ループの中でのみ利用可能
ページング
コンテンツの投稿部分はできましたが、表示件数が10件( 設定の初期値 )を超えると現状それ以上表示ができません。ですので、ページング(ページャー、ページネーションともいう)を実装して、2ページ、3ページ目とページを送れるようにしましょう。
テーマにこれを実装すると、テーマを変更した場合ページング機能が失われてしまうので、プラグインを導入する手段もありますが、どういう処理を書くのか?を理解するためにも、テーマ側で実装していきます。
その前に、1ページに表示する数を減らしてみましょう。
設定 > 表示設定 から 「1ページに表示する最大投稿数」の値を変更します。とりあえず3とかにすれば、4つ目以降は2ページ目に表示されるようになります。
投稿を3以下しか登録してない場合は、投稿数を増やしておきましょう。
では、ページングの部分を変更しましょう。
index.php <ul class="p-pagenation"> <li class="prevpostslink"><a rel="next" href="#">Prev</a></li> <li class="nextpostslink"><a rel="next" href="#">Next</a></li> </ul>
を、以下のようにします。
index.php <?php if ( $wp_query -> max_num_pages > 1 ) : //ページ数が1を超える場合に処理 ?> <ul class="p-pagenation"> <li class="prevpostslink"><?php next_posts_link( 'Prev' ); ?></li> <li class="prevpostslink"><?php previous_posts_link( 'Next' ); ?></li> </ul> <?php endif; ?>
冒頭の条件分岐により、ページ数が1しかない場合はページングが出力されません。
- 前のページを表示する・・・Codex: テンプレートタグ/next_posts_link
- 次のページを表示する・・・Codex: テンプレートタグ/previous_posts_link
これらはページ送り先が無い最初のページ、もしくは最後のページの場合にはテキストリンクが出力されません。
ページ送りなので、次を表示するということは2ページ目、3ページ目となりますが、投稿の表示順番は新しい記事から順番に並んでいますので、2ページめに進むということは、今よりも前に書かれた投稿を表示するという事になります。
関数名が next_posts_link なのに前のページを見るという風になっているのはそのためです。
previous_posts_link に関しても同じ意味合いになっています。
間違いそうなので気をつけましょう。
コンテンツ部分のWordPress化まとめ
ここまでで index.php は終了です。ソースは下記のようになっていると思います。
index.php <?php get_header(); ?> <div class="c-wrap"> <div class="c-grid"> <div class="p-contents"> <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="post__ttl"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <ul class="post__meta"> <li class="post__meta__item"> <date class="post__meta__date"><?php echo get_the_date(); ?></date> </li> <li class="post__meta__item"><i class="fa fa-folder" aria-hidden="true"><?php the_category( ', ' ); ?></i></li> <li class="post__meta__item"><i class="fa fa-tag" aria-hidden="true"><?php the_tags( '' ); ?></i></li> </ul> <?php the_post_thumbnail(); ?> <?php the_content( '続きを読む' ); ?> </div> <?php endwhile; else : ?><p>表示する記事がありません</p><?php endif; ?> </div> <?php if ( $wp_query -> max_num_pages > 1 ) : ?> <ul class="p-pagenation"> <li class="prevpostslink"><?php next_posts_link( 'Prev' ); ?></li> <li class="prevpostslink"><?php previous_posts_link( 'Next' ); ?></li> </ul> <?php endif; ?> <?php get_sidebar(); ?> </div> </div> <?php get_footer(); ?>
ポイントとしては
- 投稿データの表示にはループ処理を行う。
- テンプレートタグはループの中でしか使えない物が存在する
- 1ページに表示する投稿件数は管理画面で設定ができる
- ページングはプラグインで実装する手段もあり、テーマを変えても機能を残す場合はプラグインを採用する
sidebar.phpの編集 ウィジェットを使ってサイドバーを実装する
サイドバーは sidebar.php というテンプレートにしていますが、もう少し使いやすくしてみます。
WordPressにはウィジェットという機能があります。これは、サンプルのカテゴリリストやタグリストなど、それぞれパーツ化し、必要な箇所でそれを読み込んで表示出来る機能の事をいいます。
パーツの設定は管理画面で行えるので、パーツの取り外しや設定が容易になります。今回はこれを使って実装していきます。
まず、現状だとテーマにウィジェットを扱う機能が備わっていません。
これまででてきたように、functions.php にウィジェットが扱えるよう設定を書き込みます。
functions.php function wpbeg_widgets_init() { register_sidebar ( array( 'name' => 'カテゴリーウィジェット', 'id' => 'category_widget', 'description' => 'カテゴリー用ウィジェットです', 'before_widget' => '<div id="%1$s" class="widget %2$s">', 'after_widget' => '</div>', 'before_title' => '<h2><i class="fa fa-folder-open" aria-hidden="true"></i>', 'after_title' => "</h2>\n", ) ); } add_action( 'widgets_init', 'wpbeg_widgets_init' );
これで管理画面の外観にウィジェットという項目が追加されています。
設定した項目は
- name – 画像に書いているnameの部分で出力されます
- id – ウィジェットを呼び出す際のid
- description – 画像に書いているdescription
- before_widget – フロント側で出力される際、ウィジェットの前に挿入されるタグや文言です。id=”%1$s”と記述しておくと自動的にidが振られます。
- after_widget – フロントで出力される際、ウィジェットの後ろに挿入されるタグや文言です。
- before_title – ウィジェットのタイトルの前に挿入される文字列やタグです
- after_title – ウィジェットのタイトルの後ろに挿入される文字列やタグです
設定が反映されて画面のように出力されていれば、左側にある項目から表示するものを選択します。
選択方法は
A. ドラッグアンドドロップで決定
B. 選択して追加するウィジェットを選択し、ウィジェットを追加をクリック
あとは表示するタイトルを記入して保存すれば完了です。
次は sidebar.php を編集します。
<div class=”p-sidebar”> のすぐ下に下記ソースを追加します。
sidebar.php <div class="p-sidebar"> <?php if ( is_active_sidebar( 'category_widget' ) ) : dynamic_sidebar( 'category_widget' ); else: ?> <div class="widget"> <h2>No Widget</h2> <p>ウィジットは設定されていません。</p> </div> <?php endif; ?>
- if ( is_active_sidebar( ‘category_widget’ ) ) ・・・ サイドバーID category_widget が有効になっているかの条件判定です。有効になっていない場合は「ウィジェットが設定されていません。」というエラー通知を出力します。 Codex: 関数リファレンス/is_active_sidebar
- dynamic_sidebar( ‘category_widget’ ) ・・・ 設定したウィジェットを呼び出します Codex: 関数リファレンス/dynamic_sidebar
フロント側でこのようにウィジェットで登録したものが表示されているはずです。
ウィジェットはひとつの中に複数含めることもできますし、ウィジェット自体を複数設定することもできます。
今回ウィジェットタイトルの前に表示するアイコンが全て違うので、ウィジェットをあと2つ追加してみましょう。
functions.php に2つ分のウィジェットを追加します。wpbeg_widgets_init() 関数の中に含めてください。
functions.php register_sidebar( array( 'name' => 'タグウィジェット', 'id' => 'tag_widget', 'description' => 'タグ用ウィジェットです', 'before_widget' => '<div id="%1$s" class="widget %2$s">', 'after_widget' => '</div>', 'before_title' => '<h2><i class="fa fa-tags" aria-hidden="true"></i>', 'after_title' => "</h2>\n", ) ); register_sidebar( array( 'name' => 'アーカイブウィジェット', 'id' => 'archive_widget', 'description' => 'アーカイブ用ウィジェットです', 'before_widget' => '<div id="%1$s" class="widget %2$s">', 'after_widget' => '</div>', 'before_title' => '<h2><i class="fa fa-archive" aria-hidden="true"></i>', 'after_title' => "</h2>\n", ) );
また、複数作る場合、IDが重複しないように注意してください。
functions.php の編集が終わったら、管理画面を更新してそれぞれ必要なウィジェットを登録します
最後に sidebar.php を編集します。この時にサンプルにあった html は削除してしまいましょう
sidebar.phpの編集まとめ
sidebar.php <div class="p-sidebar"> <?php if ( is_active_sidebar( 'category_widget' ) ) : dynamic_sidebar( 'category_widget' ); else: ?> <div class="widget"> <h2>No Widget</h2> <p>ウィジットは設定されていません。</p> </div> <?php endif; ?> <?php if ( is_active_sidebar( 'tag_widget' ) ) : dynamic_sidebar( 'tag_widget' ); else: ?> <div class="widget"> <h2>No Widget</h2> <p>ウィジットは設定されていません。</p> </div> <?php endif; ?> <?php if ( is_active_sidebar( 'archive_widget' ) ) : dynamic_sidebar( 'archive_widget' ); else: ?> <div class="widget"> <h2>No Widget</h2> <p>ウィジットは設定されていません。</p> </div> <?php endif; ?> </div>
フロント側はこのようになっています。
sidebar.php は以上です。
ウィジェットはサイドバーだけでなくフッターやヘッダーなどにでも利用できます。
サイトに応じて色々作ってみましょう。
ポイントとしては
- テーマにウィジェットを対応させないと使えない
- functions.php に設定を複数書くことで、複数のウィジェットを作れる
- ひとつのウィジェットに表示するものをまとめることも出来る
- sidebar.php で表示したいウィジェットを呼び出すコードを記述する
- ウィジェットはサイドバー以外にも表示できる
footer.php を編集する
footer.php に記述しているものは少ないので、それほどやることはありません。
copyrightに記述しているサイト名を header.php 同様 <?php bloginfo( ‘name’ ); ?> にしておきましょう。
また、footer.php は header.php の wp_head() と同じように必ず wp_footer() を読み込んでおかねばなりません。
footer.php <footer class="footer"> <p class="footer__copyright"><small>© <?php bloginfo( 'name' ); ?> 2017</small></p> </footer> <?php wp_footer(); ?> </body> </html>
wp_footer WordPressがページを表示する際に必要なコードを出力します。プラグインなどが出力する JavaScript もこの関数を通して出力されるので、必ず記述しておく必要があります。場所は </body> の前になります。
single.php の編集 個別投稿の表示
ここまでで index.php 全体の処理は完了し、共通パーツの組み込みが終わりました。
しかしあと single.php と、page.php の2つが残っているのでこれらを編集していきましょう。
まず、single.php を index.php と同様、各パーツをインクルードタグを使ってテンプレートを読み込むよう編集します。
- ヘッダー・・・get_header
- サイドバー・・・get_sidebar
- フッター・・・get_footer
ループ処理からコンテンツの部分は以下のようになります。
single.php <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="post__ttl"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <ul class="post__meta"> <li class="post__meta__item"> <date class="post__meta__date"><?php echo get_the_date(); ?></date> </li> <li class="post__meta__item"><i class="fa fa-folder" aria-hidden="true"><?php the_category( ', ' ); ?></i></li> <li class="post__meta__item"><i class="fa fa-tag" aria-hidden="true"><?php the_tags( '' ); ?></i></li> </ul> <?php the_post_thumbnail(); ?> <?php the_content(); ?> <?php $args = array ( 'before' => '<div class="page-split">', 'after' => '</div>', 'link_before' => '<span>', 'link_after' => '</span>', ); wp_link_pages( $args ); ?> </div> <?php endwhile; else : ?><p>表示する記事がありません</p><?php endif; ?>
index.php と異なるのは <?php the_content(); ?> で、single.php のような個別投稿表示用テンプレートでは「続きを読む」の記述は不要です。
投稿表示用のスタイリング
また、サンプルの single.php には見出しタグやリストタグなどをスタイルシートでスタイリングを行っていますが、ご自身でコーディングをする場合は管理画面の投稿にある WordPress の WYSIWYG エディタで入力できるものを投稿で作っておきましょう。
実際にテーマを作る場合は、このエディタで出力されるタグに対してスタイリングしておく必要があります。
でないと、エディタで見出しタグや左寄せなどを指定しても何も変化のしないプレーンなテキストになってしまいます。
また、今回は style.css のみを作っていますがこの状態だとエディタの見た目はただのエディタになりますので、フロントでの見え方はプレビューを見るしかありません。もしエディターの見た目をフロント側に合わせたい場合は別途 editor-style.css を用意し、style.css 同様読み込みの設定を functions.php に記述することで、エディタ側スタイリングができるようになります。
あとは editor-style.css に style.css と同じスタイリングを記述することでフロント側とエディタ側の見た目を合わせることができます。
Codex: 関数リファレンス/add_editor_style
2017年10月31日 追加: テーマをeditor-styleに対応させました。
CSSディレクトリに editor-style.css を追加し、wpbeg.css をインポートさせます。
editor-style.css
@import url( 'wpbeg.css' );
これで簡単にeditor-styleは作れますが、不要なタグ等も入ってしまうので、必要なcssだけをコピーして持ってきたり、gulpなどでsassなどを使っている場合は、必要なものだけをeditor.scssに吐き出す設定を書き込むと更に良くなります。
後は functions.php に
functions.php function wpbeg_theme_add_editor_styles() { add_editor_style( get_template_directory_uri() . "/css/editor-style.css" ); } add_action( 'admin_init', 'wpbeg_theme_add_editor_styles' );
と記述すれば、テーマ側で editor-style.css を認識するようになります。
ページ内分割機能
single.php では投稿に <!–nextpage–> と記述することでページの分割が可能になります。
サンプルではページ分割のスタイルを表示する為に下記の記述を行っています。
single.php <?php $args = array ( //出力のフォーマットを設定 'before' => '<div class="page-split">', //ラッパー用の開始タグ 'after' => '</div>', //ラッパーのとじタグ 'link_before' => '<span>', //リンクの前に表示するタグ 'link_after' => '</span>', //リンクの後ろに表示するタグ ); wp_link_pages( $args ); //ページ分割された投稿についてページリンクを表示します。 ?>
投稿者情報の出力
WordPressに登録しているユーザー情報( 最初に作成したアカウント含む )を出力します。情報を編集したい場合は管理画面から行えるので下記を参考してください。
今回はとりあえず 管理画面の ユーザー > あなたのプロフィール からプロフィール情報を編集して保存しましょう。
投稿者情報のソースは現在
<div class="post__author"> <p class="post__author__ttl">投稿者</p><img class="avatar" src="images/common/ico/author_default.png" alt="auhor"> <div class="post__author__name"><a href="#">投稿者名</a></div> <p class="post__author__comment">投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。投稿者紹介文章がはいります。</p> </div>
となっています。これを下記のように変更します。
single.php <div class="post__author"> <p class="post__author__ttl">投稿者</p> <?php echo get_avatar( get_the_author_meta( 'ID' ), 60 ); ?> <div class="post__author__name"><?php the_author_posts_link(); ?></div> <p class="post__author__comment"><?php echo get_the_author_meta( 'description' ) ?></p> </div>
そして、この処理は現在ループの外側にあると思いますので、ループの中に含めてください。
echo get_avatar( get_the_author_meta( ‘ID’ ) ・・・WordPressのプロフィールアイコンは Gravatar という外部サービスと連動していて、ここで登録しているアイコンを表示することができます。今回はこれを利用するためにこの関数を指定しています。
- the_author_posts_link() ・・・投稿者の全投稿アーカイブへのリンクを取得して表示します。 Codex: テンプレートタグ/the_author_posts_link
- get_the_author_meta() ・・・ユーザーのメタ情報を取得して表示します。 Codex: テンプレートタグ/get_author_posts_url
これで投稿者へのリンク付き情報が表示できました。
今回の記述はループ内で記述しているので表示できていますが、ループ外で表示させる場合は別の記述になるので注意してください。
コメント部分の編集
まずコメントの表示部分をテンプレート化します。
<div class="p-comment"> <h2 class="p-comment__ttl">Comment</h2> <ol class="p-comment__list"> <li class="comment parent"> <div class="comment-body"> <div class="comment-author"><img class="avatar" src="images/common/ico/author_default.png" alt="auhor"> <cite>ユーザー名</cite><span>より:</span> </div> <div class="comment-meta commentmetadata"><a href="#">Octber 11, 2017 at 11:45 pm</a></div> <p>コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。</p> <div class="reply"><a class="comment-reply-link" href="#">返信</a></div> </div> <ul class="children"> <li class="comment bypostauthor"> <div class="comment-body"> <div class="comment-author"><img class="avatar" src="images/common/ico/author_default.png" alt="auhor"> <cite>ユーザー名</cite><span>より:</span> </div> <div class="comment-meta commentmetadata"><a href="#">Octber 11, 2017 at 11:45 pm</a></div> <p>コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。コメントが入ります。</p> <div class="reply"><a class="comment-reply-link" href="#">返信</a></div> </div> </li> </ul> </li> </ol> <div class="comment-page-link"><a class="prev page-numbers" href="#">« 前へ</a></a><a class="page-numbers" href="#">1</a><a class="page-numbers" href="#">2</a><a class="page-numbers" href="#">3</a><span class="page-numbers current">4</span></div>
これを
<div class="p-comment"> <?php if( have_comments() ): ?> <h2 id="comments" class="p-comment__ttl">Comment</h2> <ul class="p-comment__list"> <?php wp_list_comments( 'avatar_size=60' ); ?> </ul> <?php endif; ?>
こうします。かなりシンプルですよね。
まず、コメントがない場合はこの部分の出力は不要なので、 have_comments をつかって、コメントの有無を条件分岐します。 Codex: 関数リファレンス/have_comments
コメントが有る場合コメントのタイトルを表示し、コメント部分を表示するラップ部分を出力しておきます。
というのも、コメント部分については自動的に <li> タグを使って出力されるので、ラップ部分は <ul> か <ol> タグになります。
そして、実際のコメント部分の出力は wp_list_comments( ‘avatar_size=60’ ); の部分が該当します。 Codex: テンプレートタグ/wp_list_comments
そしてこの部分を comments.php として保存し single.php では comments_template を使ってテンプレートを呼び出します。
<div class="p-comment"> <?php if( have_comments() ): ?> <h2 id="comments" class="p-comment__ttl">Comment</h2> <ul class="p-comment__list"> <?php wp_list_comments( 'avatar_size=60' ); ?> </ul> <?php endif; ?>
<?php comments_template(); ?>
そしてこれもループ処理の中に移動させます。
コメントフォームの編集
コメントの表示はできたので、コメントフォームの部分をテンプレート化します。
まず、コメントフォームについても comments.php に記述します。
先程のコメント表示の部分の下に下記ソースを記述します。
comments.php <?php $args = array( 'title_reply' => 'Leave a Reply', 'label_submit' => ' POST COMMENT', ); comment_form( $args ); ?> </div>
single.php に記述していた部分は不要なので削除します。コメント部分のソースは下記のみになります。
<?php comments_template(); ?>
comments.php は下記のようになっているはずです。
comments.php <div class="p-comment"> <?php if( have_comments() ): ?> <h2 id="comments" class="p-comment__ttl">Comment</h2> <ul class="p-comment__list"> <?php wp_list_comments( 'avatar_size=60' ); ?> </ul> <?php endif; ?> <?php $args = array( 'title_reply' => 'Leave a Reply', 'label_submit' => ' POST COMMENT', ); comment_form( $args ); ?> </div>
そして、フロント側に関しては
ログイン時
ログアウト時
になっていると思います。
ログアウトした状態でコメントを行い、ログインした状態で返信ボタンをクリックしてみてください。画面がフォームの箇所までスクロールすると思います。
これは comments.php を記述す際
<h2 id=”comments” class=”p-comment__ttl”>Comment</h2>
に id =”comments” を指定しているために起こる挙動で、これが抜けるとフォームへのスクロール移動ができなくなってしまうので注意してください。
また、投稿されたコメントは承認されるまで出現しません。
管理画面の コメント > 承認する からコメントを承認することで、フロント側に出現します。
このコメントの部分については、
管理画面の 設定 > ディスカッション の項目から設定を変更することで挙動を変更することができます。
現時点でテーマディレクトリ内の構成は以下の通りとなっているはずです。
wpbeg/comments.php /css/wpbeg.css /footer.php /functions.php /header.php /images/ /index.php /page.php /screenshot.png /searchform.php /sidebar.php /single.php /style.css
ページングの編集
index.php では前のページ、次のページに切り替えるためのページングになっていましたが、 single.php では 前の記事、次の記事というページングに変更します。
<?php if ( $wp_query -> max_num_pages > 1 ) : ?> <ul class="p-pagenation"> <li class="prevpostslink"><?php next_posts_link( 'Prev' ); ?></li> <li class="prevpostslink"><?php previous_posts_link( 'Next' ); ?></li> </ul> <?php endif; ?>
これを下記のように変更します。
<?php if( get_previous_post() || get_next_post() ) : ?> <ul class="p-pagenation"> <?php if ( get_previous_post() ) : ?> <li class="prevpostslink"><?php previous_post_link( '%link', 'Prev' ); ?></li> <?php endif; ?> <?php if( get_next_post() ): ?> <li class="prevpostslink"><?php next_post_link( '%link', 'Next' ); ?></li> <?php endif; ?> </ul> <?php endif; ?>
そしてこのソースもループ処理の中に入れます。
変更になったテンプレートタグは
- Codex: テンプレートタグ/previous_post_link ・・・現在の投稿から見て日付順でひとつ前の投稿へのリンクを表示します。
- Codex: テンプレートタグ/next_post_link ・・・現在の投稿から見て日付順で次の投稿へのリンクを表示します。
また、条件分岐に get_previous_post() || get_next_post() ) とすることで、前の記事もしくは次の記事がない場合は表示を行わないという判定をしています。
その上で、 get_previous_post の条件判定で前の投稿があればリンクを表示。 get_next_post の条件判定で次の投稿があればリンクを表示という処理を行っています。
single.php の編集まとめ
ここまでで single.php の編集が完了しました。
殆どの処理がループの中に入りました。
single.php <?php get_header(); ?> <div class="c-wrap"> <div class="c-grid"> <div class="p-contents"> <div class="p-post"> <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="post__ttl"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <ul class="post__meta"> <li class="post__meta__item"> <date class="post__meta__date"><?php echo get_the_date(); ?></date> </li> <li class="post__meta__item"><i class="fa fa-folder" aria-hidden="true"><?php the_category( ', ' ); ?></i></li> <li class="post__meta__item"><i class="fa fa-tag" aria-hidden="true"><?php the_tags( '' ); ?></i></li> </ul> <?php the_post_thumbnail(); ?> <?php the_content(); ?> <?php $args = array ( 'before' => '<div class="page-split">', 'after' => '</div>', 'link_before' => '<span>', 'link_after' => '</span>', ); wp_link_pages( $args ); ?> </div> <div class="post__author"> <p class="post__author__ttl">投稿者</p> <?php echo get_avatar( get_the_author_meta( 'ID' ), 60 ); ?> <div class="post__author__name"><?php the_author_posts_link(); ?></div> <p class="post__author__comment"><?php the_author_meta( 'description' ) ?></p> </div> <?php comments_template(); ?> <?php if( get_previous_post() || get_next_post() ) : ?> <ul class="p-pagenation"> <?php if ( get_previous_post() ) : ?> <li class="prevpostslink"><?php previous_post_link( '%link', 'Prev' ); ?></li> <?php endif; ?> <?php if( get_next_post() ): ?> <li class="prevpostslink"><?php next_post_link( '%link', 'Next' ); ?></li> <?php endif; ?> </ul> <?php endif; ?> <?php endwhile; else : ?><p>表示する記事がありません</p><?php endif; ?> </div> </div> <?php get_sidebar(); ?> </div> </div> <?php get_footer(); ?>
wpbeg/comments.php /css/wpbeg.css /footer.php /functions.php /header.php /images/ /index.php /page.php /screenshot.png /searchform.php /sidebar.php /single.php /style.css
ここでのポイントは
- インクルードタグは index.php とほぼ同じ使い方ができる
- 投稿者情報、コメント、ページングはループ処理の中に移動させる
- コメントはテンプレートする
- コメントフォームには id=”comment” を指定し、フォームへ移動できるようにする
- ページング処理は index.phpと書き方が異なる
page.php 固定ページのテンプレートを編集する
最後のファイルになる、固定ページのテンプレートです。
まず固定ページにタイトルだけ入れていた About のページを編集しましょう 管理画面 > 固定ページ一覧 から編集します。
テンプレートの方は、中身が殆ど index.php と同じなので、index.php の中身をまるごとコピーして page.php の中身を上書きしてください。
それが出来たら不要な箇所を削除していきます。
page.php <?php get_header(); ?> <div class="c-wrap"> <div class="c-grid"> <div class="p-contents"> <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="post__ttl"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <ul class="post__meta"> //削除 <li class="post__meta__item"> //削除 <date class="post__meta__date"><?php echo get_the_date(); ?></date> //削除 </li> //削除 <li class="post__meta__item"><i class="fa fa-folder" aria-hidden="true"><?php the_category( ', ' ); ?></i></li> //削除 <li class="post__meta__item"><i class="fa fa-tag" aria-hidden="true"><?php the_tags( '' ); ?></i></li> //削除 </ul> //削除 <?php the_post_thumbnail(); ?> <?php the_content( '続きを読む' ); ?> // 続きを読むは削除 </div> <?php endwhile; else : ?><p>表示する記事がありません</p><?php endif; ?> </div> <?php if ( $wp_query -> max_num_pages > 1 ) : ?> //削除 <ul class="p-pagenation"> //削除 <li class="prevpostslink"><?php next_posts_link( 'Prev' ); ?></li> //削除 <li class="prevpostslink"><?php previous_posts_link( 'Next' ); ?></li> //削除 </ul> //削除 <?php endif; ?> //削除 <?php get_sidebar(); ?> </div> </div> <?php get_footer(); ?>
また、固定ページでもコメントを受け付けられるようにループの中に <?php comments_template(); ?> を追加し、最終的に下記となります。
page.php <?php get_header(); ?> <div class="c-wrap"> <div class="c-grid"> <div class="p-contents"> <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="post__ttl"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <?php the_post_thumbnail(); ?> <?php the_content(); ?> <?php comments_template(); ?> </div> <?php endwhile; else : ?><p>表示する記事がありません</p><?php endif; ?> </div> <?php get_sidebar(); ?> </div> </div> <?php get_footer(); ?>
実際のページを見てみると
コメントがでていません。
この場合は固定ページの投稿のディスカッションでコメントが有効になっていない為です。
管理画面の上部に表示オプションというのがあり、デフォルトでは非表示になっている項目が幾つかあります。固定ページのディスカッションも同様に非表示になっているので、チェックを入れて表示します。
すると投稿ブロックの下側にディスカッションの項目が出現し、その中に 「コメントの投稿を許可」 があり、そのチェックが外れています。これをチェックして更新することで、コメント機能が有効になります。
page.php編集のまとめ
ポイントは
- index.php から流用すると楽
- 固定ページで不要なものは削除する
- コメント欄を利用する場合は、固定ページの投稿のディスカッション設定から、コメント機能を有効にする
フィードの設定
テンプレートの設定は全て完了しました。
テーマとしてはこれで見た目は挙動しますが、WordPress はブログなのでフィードと言うものが存在します。
しかし、これもデフォルトでは機能として持たないので、テーマでの利用を許可します。
functions.php に以下を追加しましょう。
add_theme_support( ‘automatic-feed-links’ );
フロント側でソースを確認すると、下記のようにフィードが出現しています。
Codex: 関数リファレンス/add_theme_support
エスケープ処理
ヘッダーでブログのURLを習得する際に下記のような記述を行っていました。
esc_url( home_url( ‘/’ ) )
home_url( ‘/’ ) 単体でも取得はできるのですが、URLはそのまま出力すると、そこに含まれる文字列によってはURLとして利用できない文字列や空白が入る恐れがあります。
それを本来であれば、不要な文字列を削除したり安全な文字列に置き換えたりしないといけないのですが、それを行ってくれているのが esc_url となり、この安全な処理自体をエスケープ処理と言います。
今回のサンプルではWordPressがデータを取得し表示まで行っている関数をできるだけ使っていますが、データを取得し、自分の好みに合わせてタグを整形して出力するといったことも当然可能です。
しかし、取得から出力まで行う関数は、データが出力される際にエスケープ処理を施して出力してくれています。
例えば、投稿のコンテンツ部分を出力するのに the_content() を使って出力していますが、データを出力せず取得のみを行う get_the_content という関数も存在します。
コンテンツ部分をそのまま出力せず、受け取ったデータを加工して出力する場合には便利ですし、取得したデータをそのまま echo することでもやりたい事の実現自体は可能です。
しかし、この方法だと当然そのまま出力されてしまうので、もしコンテンツの部分にJavaScriptのソースコードが記述されていたり、出力されては危険な文字列がそのまま出力されてしまうとすればかなり危険です。
それをコンテンツの投稿者が手動ですべて安全な文字列に置き換えて記述すれば問題は無いかもしれませんが、全てを把握することは難しいですし、そもそも投稿する人がそこに対してどれほど意識しているかは、テーマを作る人からすればわからない領域です。
そういった問題を容易に解決するため、get_the_content を使って出力する場合は esc_html を使って出力することで解決できますし、そもそも the_content() を利用すればエスケープ処理をわざわざ挟む手間も省けます。
WordPress にはこういったエスケープ処理がいくつか用意されており、データを自分で出力する場合はこれらを活用することで安全なテーマ開発を行うことが出来ます。
- Codex: 関数リファレンス/esc_html ・・・HTML ブロックをエスケープ
- Codex: 関数リファレンス/esc_attr ・・・< > & ” ‘ (小なり、大なり、アンパサンド、ダブルクォート、シングルクォート) 文字参照をエンコード
- Codex: 関数リファレンス/esc_url ・・・テキストや属性などのURLを無害化
functions.phpの役割
テーマに機能を持たせる場合に利用した functions.php ですが、このファイルで様々な事ができる事と、ここで設定したものをプラグインディレクトリに記述することで簡単にプラグインにもできます。
functions.php だとそのテーマでしか有効にならないのですが、プラグインにしておくとテーマが変わっても機能はそのまま残るので、ここに書いた処理でテーマが変わっても残しておきたいものはプラグインにしておくと便利です。
そもそもWordPressは見た目の部分に当たるテーマと、機能の部分にあたるプラグインとが存在していて、どっちを使うと良いのか?と迷うことがよくあります。
そんなときは、テーマを変えても機能させておきたいのか、そうでないのかで判断すると考えやすくていいかなと思います。
テーマチェック
テーマの開発が一通り終わったらテーマチェックをかけてみましょう
目視のチェックももちろんやりますが、WordPressの安全性などは難しいのでプラグインを使ってやるのが便利です。
WordPressのプラグインは管理画面からインストールできるのでそこからやってみましょう。
- 管理画面の プラグイン > 新規追加 を選択
- キーワードに theme check 入力すれば出てくるので
- 今すぐにインストールを選択
- インストールが終わるとボタンが 有効化 に変わるので、有効化します。
- 有効化すればプラグイン自体は使えるようなるのですが、このプラグインはWordPressのデバッグモードをオンにしないといけないので wp-config.php を編集してデバッグモードをオンにします。
デバッグモード
WordPressの開発時に利用することで、エラーなどを出力してくれる機能です。通常は無効になっていますので、これを有効にすることで利用できるようになります。
WordPress本体のルートの中( Local by Flywheel の場合開発 ディレクトリのトップ/app/public/ ) にある wp-config.php を編集します
いくつか define() が並んでいると思いますので、この一番下あたりに下記を追加してください。
define( ‘WP_DEBUG’, true );
以上で使えるようになりますので、 管理画面 > 外観 > Theme Check からテーマを選択して テスト実行 を押してください。
少し時間がかかったりするので、終わるまで待ちます。
チェックが終わると下記のようにメッセーが表示されます。
ここでは必須の項目や警告、情報と言ったヒントなどが出てくるので、チェックしていきます。
今回の開発で出てきた必須の項目を見てみます。
- 必須: テーマの css には .wp-caption の css クラスが必要です。
- 必須: テーマの css には .wp-caption-text の css クラスが必要です。
- 必須: テーマの css には .sticky の css クラスが必要です。
- 必須: テーマの css には .gallery-caption の css クラスが必要です。
- 必須: テーマの css には .bypostauthor の css クラスが必要です。
- 必須: テーマ CSS 中に CSS クラス .screen-reader-text が必要です。Codex で実例を参照してください。
- 必須: 待機状態のコメント返信のスクリプトを見つけることができません。プラグインとテーマの移行/2.7/Enhanced Comment Displayをご覧ください。 <?php if ( is_singular() ) wp_enqueue_script( “comment-reply” ); ?>
- 必須: テキストドメインがテーマのスラッグと一致しません。現在のテキストドメイン: このテーマの正しいスラッグとテキストドメインは wpbeg です。
- 必須: コンテンツの幅が定義されていません。例:
if ( ! isset( $content_width ) ) $content_width = 900;
必須: テーマの css には .wp-caption の css クラスが必要です。
.wp-caption というのは、投稿に画像を挿入する際、キャプションを登録すると画像の下にキャプション用のテキストが出現します。
その場合、画像とキャプションを div タグでくくり、その div タグに .wp-caption というクラスが付くのですが、それのスタイリングが無いために出てきたエラーになります。これを解決するため
.wp-caption {
font-size: 1.3rem
}
を新たに追加しました
必須: テーマの css には .wp-caption-text の css クラスが必要です。
こちらは .wp-caption 内部のテキスト箇所に対して、 p タグに .wp-caption-text というタグが付くのですが、それのスタイリングが無いために出てきたエラーになります。これを解決するため
.wp-caption-text {
margin-top: -20px;
}
を新たに追加しました
必須: テーマの css には .sticky の css クラスが必要です。
.sticky は投稿した記事を先頭に固定して表示する場合に付与されるクラスになります。
通常 WordPress の投稿は記事の新しいものから順番に並んでいますが、先頭固定にするとその順番よりも前に表示されるので、特別常時知らせておきたい投稿などを固定表示して目立たせる時などに利用します。
先頭固定するには、投稿の下記の部分で指定ができます。
.sticky {
padding: 20px;
background: #f3f3f3;
}
他の投稿と差別化するために、背景色を変更してパディングを設けました。
必須: テーマの css には .gallery-caption の css クラスが必要です。
投稿に gallery というショートコードを挿入すると、ギャラリーを簡単に表示ができます。
このギャラリーは編集することで、画像を入れ替えたりするのですが、ここで使われるのが .gallery-caption になります。
.gallery-caption {
font-size: 1.3rem;
}
を新たに当てました。
必須: テーマの css には .bypostauthor の css クラスが必要です。
これは、コメント部分で、管理者がコメントした場合、管理者以外のコメントと区別させるためのクラスになります。
.bypostauthor {
padding: 20px;
background: #f0f8ff;
}
背景色を変えて差別化しました
必須: テーマ CSS 中に CSS クラス .screen-reader-text が必要です。Codex で実例を参照してください。
これはアクセシビリティに関するクラスで、スクリーンリーダーなどで読ませる場合には必要になるが、デザイン上フロント側で見せない物がある時などに使うクラスです。
コーディングをどうするかというのは Codex を参照してください。とのことなので見てみると
/* Text meant only for screen readers. */
.screen-reader-text {
clip: rect(1px, 1px, 1px, 1px);
position: absolute !important;
white-space: nowrap;
height: 1px;
width: 1px;
overflow: hidden;
}
.screen-reader-text:focus {
background-color: #f1f1f1;
border-radius: 3px;
box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
clip: auto !important;
color: #21759b;
display: block;
font-size: 14px;
font-size: 0.875rem;
font-weight: bold;
height: auto;
left: 5px;
line-height: normal;
padding: 15px 23px 14px;
text-decoration: none;
top: 5px;
width: auto;
z-index: 100000; /* Above WP toolbar. */
}
となっています。スタイルについては特に変更する必要性が無さそうなので、このまま実装し、今回はテンプレートのsearchform.php を編集しました。
もともとはデザインを再現するために
<form class="p-search-form" id="searchform">
<input class="p-search-form__keyword" placeholder="キーワード">
<input class="p-search-form__submit" id="searchsubmit" type="submit" value="検索">
</form>
としていましたが、これだとフォームに必要な label がありません。
ですが、この .screen-reader-text を使って下記のように変更しました。
<form class="p-search-form" id="searchform">
<label class="screen-reader-text" for="s">検索:</label>
<input class="p-search-form__keyword" placeholder="キーワード">
<input class="p-search-form__submit" id="searchsubmit" type="submit" value="検索">
</form>
こうすることでフロント側では見せないようにしつつも、ソースには label が存在するのでスクリーンリーダーなどでは認識されるという事になります。
必須: 待機状態のコメント返信のスクリプトを見つけることができません。プラグインとテーマの移行/2.7/Enhanced Comment Displayをご覧ください。<?php if ( is_singular() ) wp_enqueue_script( “comment-reply” ); ?>
これはコメントをテンプレート化する際に、返信をおこなう場合フォームへスムーズに移動する処理がありましたが、現状のままだと単純に移動するだけになります。
この挙動は現状変更されており、本来であれば返信を押したブロックの下にコメントフォームが出現するのが正しい挙動となります。
それを適用するためには、 header.php にかいた <?php wp_head(); ?> の1行上に <?php if ( is_singular() ) wp_enqueue_script( “comment-reply” ); ?> を挿入することで実現できるようになります。
<?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?>
<?php wp_head(); ?>
必須: テキストドメインがテーマのスラッグと一致しません。現在のテキストドメイン: このテーマの正しいスラッグとテキストドメインは wpbeg です。
テキストドメインがテーマのスラッグと一致していない場合に出現するエラーになります。
ですが、今回はそもそも一度もテキストドメインを利用していません。
どうやら一度も使っていない場合でもこのエラーは出るようです。
テーマを公開せず、自分で使うためなどであればここは飛ばしても問題ないと思いますが、今回はせっかくなので後ほど翻訳についても触れておきます。
必須: コンテンツの幅が定義されていません。例: if ( ! isset( $content_width ) ) $content_width = 900;
これはテーマのコンテンツエリアのサイズ指定がされていないために出ているエラーです。
functions.php にコンテンツ幅を指定することで解決できます。
wpbeg に関してはコンテンツエリアを 960px にしているので、そのように記述します。
if ( ! isset( $content_width ) ) {
$content_width = 960;
}
テーマを翻訳対応する
本来テキストドメインを利用する場合、表示したい文字列の箇所を英語にしておき、他の言語に対してはそれを翻訳させる場合に利用します。
例)
<?php echo __(' search', 'wpbeg' ); ?>
本来であれば「検索」と表示するのですが、WordPressのテーマは様々な言語で使われるため 「search」 という言葉に対して、それぞれの言語で翻訳がかけられるようにテーマ開発者が指定した wpbeg というテキストドメインを使って翻訳がかかるようにします。
テーマディレクトリやプラグインディレクトリに掲載されいてるものについては GlotPress というシステムを用いて、誰でも翻訳に参加出来るようになっており、そうでないものについてはテーマやプラグインディレクトリ内に翻訳ファイルを設置して翻訳させる事になります。
テーマディレクトリに翻訳ファイルを入れる場合は、 /languages/ ディレクトリを作成し、その中に ja.po ja.mo を作って翻訳させていきます。
.mo ファイルは .poファイルをもとにして生成されるファイルで、まず .po ファイルを作らなければなりません。
WordPress が読み込むのは .mo ファイルの方になります。
これらのファイルを作成するには Poedit というソフトを使います。
試しに例で上げた search を翻訳機能を使ってやってみます。先程お伝えしたとおり languages ディレクトリを作成しましょう。
次に、searchform.php を編集します
<label class="screen-reader-text" for="s"><?php echo __(' search', 'wpbeg' ); ?></label>
翻訳のための準備が整ったので、Poedit を起動します。
起動画面はこんな感じです。
ここでソフトのメニューから ファイル > 新規カタログ を選択
- タブをソースの検索パスに切り替えます
- ベースのパスに .
- パスに .. を入力後、タブを「ソース中のキーワード」に切り替え
- キーワードに __ と _e と入力 ( 翻訳に使う文字列は __() もしくは _e() が使われるためです )
- OKをクリックします。
すると保存先を聞いてくるので、テーマディレクトリの中に作った languagesディレクトリを選択し、名前を日本語なので ja.po として保存します。( 言語によってファイルの命名規則があります )
のような画面がでたら、OKをクリックしてください。
画面の上部左側が翻訳をかけられるリストで、選択すると下側に「ソーステキスト」の箇所にキーワードが出てきます。
その下側の翻訳のところで、「検索」 と翻訳すれば、上部の対訳に翻訳した言葉が表示されます。
これで ファイル > 保存 をすれば jp.mo ファイル が保存・更新されます。
あとはこれをテーマ側で読み込めるよう functions.php に設定を書き込みます。
function wpbeg_theme_setup(){
load_theme_textdomain( 'wpbeg', get_template_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'wpbeg_theme_setup' );
- Codex: 関数リファレンス/load_theme_textdomain テキストドメインと、.mo ファイル が保存されているパス情報を書きます。
これでフロント側を見てみましょう。
ひとまず確認のために label タグ から class=”screen-reader-text” を削除しましょう。
下記のように翻訳がかかっていれば成功です。
テーマチェックを再びかけるとエラーもちゃんと消えました。
確認ができたら、削除したクラスをもとに戻しておきましょう。
テーマに翻訳ファイルを含めず、WordPressの テーマディレクトリ に公開し、GlotPress を使って翻訳したい場合は、テーマを申請が通ったら、WordSlack に参加し #requests チャンネルでテーマの PTE権限 を貰えば、翻訳の承認ができるようになります。
尚、翻訳だけなら誰でも参加できるので、普段使ってるテーマやプラグインを翻訳したいという方は、テーマやプラグインのページから、翻訳を手伝いましょうのリンク先で行うことが出来ます。
デバッグが終わったら
ここまでで必須や警告に関してはクリアできました。
改めてテーマチェックを行います
無事テストを通りました!
テーマチェックが終わったら、必ず WP_DEBUG の機能を切りましょう
define( 'WP_DEBUG', false );
テーマ作成としては今回ここまでとなりますが、テーマをテーマディレクトリに掲載したい場合は言語を全て英語にし、翻訳機能に置き換えなければなりません。
またテーマの掲載には申請が必要で、レビュアーの方にチェックしていただいてそれを通らなければなりません。
テーマレビューチームの人達もみんなボランティアでやっていますので、申請の前にガイドラインを読んで自分でチェックし、お互いのやり取りをなるべく少なくなるようにしましょう。
テストデータを使ったユニットテストなども必要ですね。
ユニットテスト
ユニットテストというのは、WordPressで登録されるであろう投稿のデータや状態など様々なパターンを想定し、作ったテーマがそれらに対応できるかのテストです。
投稿ひとつにしても、短いタイトルで正常に表示されていても、長いタイトルになると崩れてしまってはテーマとして使いづらいものになります。
それらを検証するために自分でパターンを用意するのは結構面倒になりますが、テーマテストデータを利用することでそれを簡単に行なえます。
どちらも GitHub からダウンロードできます。
データをダウンロードしてファイルを解凍すると、xml形式のデータが入っています。
あとはこれをWordPressの管理画面からインポートすればテストデータが登録されます。
インポートは管理画面の ツール > WordPress から実行できます。
初めて使う場合はツール(プラグイン)のインストールが始まります。インストールが終わったら
- インポーターの実行。
- ファイルを選択で、ダウンロードした xml ファイルを選択
- ファイルをアップロードして実行
- 投稿者を改めて割り当てる場合は各投稿ごとに設定。添付ファイルのインポートもしたければ項目にチェックし、実行。
しばらくするとインポートが完了します。
投稿データを確認して多数の投稿データが増えていれば成功です。
あとはフロント側をチェックし、崩れが気になる箇所のスタイルを調整して完了です。
まとめ
いかがでしたでしょうか?
凄く長くなりましたが、テーマの作成方法に関しては一通りかけたと思います。
とはいえ、実際の開発ではもっとテクニカルな事を行う必要がありますし、今回はテーマカスタマイザーなどにも触れていないので、まだまだできることは沢山あります。
例えばテーマカスタマイザーを使えば、テーマの色を変えたり、ロゴを変更したりといったことも管理画面の中でできるようになるので、テーマ利用者はソースコードがかけなくても自由にカスタマイズができるようになります。
今回は初めてテーマを開発される方に向けて書いた記事なので、これからもっと色々やってみたいという方は、是非Codex などを参考にして色々やってみてください。
テーマの紹介
WordPressのライセンスはGPLで、テーマやプラグインに含まれる画像やスタイルシート、JavaScriptもすべてをGPLにしているものを100%GPLと呼びます。
世の中には様々なテーマが存在していますが、使う人の自由が約束されているこのライセンスは非常にありがたいライセンスだといつも感じています。
GPLには4つの自由が約束されています。
- どんな目的に対しても、プログラムを望むままに実行する自由 (第零の自由)。
- プログラムがどのように動作しているか研究し、必要に応じて改造する自由 (第一の自由)。ソースコードへのアクセスは、この前提条件となります。
- 身近な人を助けられるよう、コピーを再配布する自由 (第二の自由)。
- 改変した版を他に配布する自由 (第三の自由)。これにより、変更がコミュニティ全体にとって利益となる機会を提供できます。ソースコードへのアクセスは、この前提条件となります。
GNUオペレーティング・システム
フリーソフトウェアファウンデーション主催
https://www.gnu.org/philosophy/free-sw.ja.html
使う人の自由。これを逆に言えばテーマやプラグインを公開する開発者にとっては、自身の利益の手段を困難にしていきます。
- 例えば、どんな目的に対してもプログラムを望むままに実行する自由を与えるということは、開発者側から利用の制限をかけることは出来ません。
- 例えば、プログラムを研究し、必要に応じて改造できる自由を与えるということは、開発者が自分のプロダクトに対してプロテクトなどはかけられなくなります。
- 例えば、コピーを再配布する自由を与えるということは、開発者のプロダクトを購入した人がそのプロダクトを無料で配布したとしても、それを開発者はそれについて制限することは出来ません。
- 例えば、改変した版を他に配布する自由を与えるということは、開発者のプロダクトを異なる人が改良し、より良くしたバージョンを配布したとしても、それを制限することは出来ません。
そしてGPLで作られたプロダクトは、それを含んだプロダクトに対して与えるライセンスは自動的にGPLとなります。
WordPressをもとに得た知識や利益は自分の力だけで培ったものではなく、これまで関わってきたたくさんの人達がいて、それを続けてきてくれたからこそ、今自分自身が仕事があったり、ブログを続けられたりしています。
それがあって、今回こういう記事を書いて、作ったものを100%GPLで公開することに至りました。
受けた恩恵は何らかの形で返していく。
それがGPLとの関わり方で、巡ってまた自分自身に何かが返ってくるだろうことにワクワクしています。
前置きが長くなりましたが、100%GPLで配布されているテーマを幾つか紹介させていただきます。
Coldbox
2カラムのテーマで、作ったのは ミルコンさん です。WordPressのテーマレビュワーもされているのでテーマの品質について非常に信頼できる開発者さんです。
マウスオーバーの挙動や、検索ボックスがアクティブになったときなどの挙動が非常に綺麗です。
modernize
シングルカラムのテーマで、投稿の詳細ページに行くと大きなヘッダー画像がインパクトあって格好いいです。
各パーツのマージンが広めにとってあり、ブログを読むことに集中できるテーマになっています。
開発者はみすみさんです
Nishiki
執筆した現在テーマ申請中ですが、9/23に行われたWordBench kobeで開発者の方が発表されていたテーマになります。
ヘッダー画像を動画にしたり、カスタマイザーで色々調整できたりと機能盛りだくさんのテーマになっています。
開発者は今村さんです
OleinPress
メディア向けに使えそうなテーマでこちらも執筆現在テーマ申請中になっています。 2017年10月16日 本記事公開数日後にWordPressテーマディレクトリに掲載されました。 開発者は WordBench Gifu のモデレーターをされている Olein さん。2カラムとヘッダーのレイアウトはサイト内のクロールがし易いので使い勝手が良いですね。
For the future
WordCamp Kansai 2016 の実行委員で作ったギャラリー用テーマです。
トップページにはタイトルなどのテキストが殆どないため、写真を一覧で見る時に非常に見やすくなっています。
PCではマウスオーバー時に出てくるタイトルの演出が綺麗です。タブレットやスマートフォンの場合はマウスオーバーという挙動がないため、その場合はタイトルが見えるようになります。
開発者は WordCamp Kansai 2017の実行委員で、メイン開発者はナターシャさんです
BizVektor
100%GPLで公開されているテーマで、これだけでもサイトは充分作れるのですが、拡張プラグインが多数販売されています。
企業向けのサイトを作るのに適したテーマで、今回紹介したブログのテーマとは大きくデザインが異なっています。
開発は株式会社ベクトルです。
SNOW MONKEY
100%GPLで公開されているテーマで、こちらは有利のテーマです。大きなビジュアルを利用したスライダーやスクロールした時の若干のパララックス効果は見ていて気持ちが良く、テーマ単体で様々な機能を持っているのも特徴です。
開発者はキタジマさんで、テーマ以外に様々なプラグインを開発して公開しています。
個人的にキタジマさんのプラグインにすごくお世話になっています。
販売価格: 16,200円
WPBEG
今回の記事で作成したWordPress版です。最終のCSS調整が残っていますがダウンロードできるようにしていますのでご自由にお使いください。もちろん100%GPLです。
CSSについてはこれからやっていきます。
WordPressはオープンソースなので、それぞれのテーマをダウンロードしたり、GitHubを見たりすることで、それぞれのテーマの中身を知ることが出来ます。
まとめの冒頭でお伝えしたように、そのソースを調べることも、実際に使うことも誰もそれを咎めたりしませんし、咎めることは出来ません。
自由に調べて、自由につかえるので、今回の勉強用のテーマを更にカスタマイズしたり、新しく自分で作ったりしてもっともっと良いものを作ってください。
そしてそれを公開してください。そうすることで自分自身の刺激にもなりますし、他の人のためにもなります。
是非、よいWordPressライフを!
2017年10月31日 テーマディレクトリへの申請のため、テーマで利用しているfont-awesomeをCDNからテーマ内でのバンドルに変更しました。ソースコードは GitHubにて確認できます。ブログの説明については変更していません。
Comments
Shin
こんにちは。大変参考になるサイトをありがとうございます。 恐れ入りますが、もしかすると [ サイトの基本情報編集 ] 項目の header.php after ですが、 <a href="">"> ↓ <a href=""> ではないかと思いましたが、いかがでしょうか?
YAT
Shinさん> 読んでいただきありがとうございます。また、ソースのご指摘ありがとうございます、こちら文中修正いたしました。非常に助かりました😊
takumi
こんにちは。大変お世話になっています。「必要なファイル」のところで、直下という言葉が二重の意味で使われており混乱を招くのではないかと思い、コメント送らせていただきます! 具体的には、最初の「テーマディレクトリの直下」の部分はテーマディレクトリを開いた一番最初のところ、次の「wpbegの直下」では「wpbegというディレクトリのすぐ下」という意味で使われているかと思うのですが、最初の意味でとらえてしまうと、wpbegを開いて一番最初にstyle.cssを作ってしまう人がいるのではないかと感じました!長文失礼いたしました!
YAT
細かいところまでご指摘ありがとうございます。 確かに分かりづらかったので、文言調整しました!
takumi
ありがとうございます! 更新に気づかずコメント訂正の返信を送ってしまいました🙇 新たに例が追加されていて、ばっちり解決していました。ありがとうございました!
takumi
申し訳ありません。 コメント訂正します。 結論から申し上げますと、「直下」という意味が二重で使われていることはありませんでした。 ただ、「必要なファイル」の"また、これらのファイルはテーマディレクトリの直下に置く必要があるので注意してください。"という箇所がテーマディレクトリの直下ではなく、wpbegの直下だと思われます。 長文失礼いたしました。何卒ご確認いただければ幸いです。
YAT
いえいえ、確認までいただいてありがとうございました! とても助かりました😊