投稿用テンプレートsingle.phpを作る(WordPressループの使い方)[WordPressテーマ作成の手順9]
今回は投稿用のテンプレート「single.php」を作る。
WordPressのテーマ作成8で、トップページの表示用のテンプレート「home.php」を作ったところからの続きです。
手順は、「home.php」をコピーして「single.php」にし、投稿記事を表示する部分をパーツテンプレート「content.php」にする。加えて前後の記事にリンクするナビも作成する。
WordPressの管理画面で書いた投稿記事は、データベースに蓄えられ、このテンプレート「single.php」に出力されてブラウザに表示される。
「single.php」では、記事を出力するためにループを使う。WordPressのループは、投稿・固定ページ・アーカイブページ用など、ほとんどのテンプレートで使う大事なPHPソース。
ループ(loop)というだけあって、繰り返し処理をしてくれる。
WordPressを使うなら、ループの概念を知っておかないと、というほど重要。
スポンサーリンク
home.phpをコピーしてsingle.phpを作る
前回作ったhome.phpをコピーし、ファイル名をsingle.phpに変更。
このsingle.phpという名のファイルがあれば、WordPressは投稿用ページとして表示する。
投稿用のテンプレートについて
WordPressは、投稿記事はsingle.phpで表示する。これが無ければindex.phpが使われる。
ちなみに「カスタム投稿タイプ」を使った場合は single-[posttype].php([posttype]は任意の名前をつける)が最優先のテンプレートになる。
(例えば、shopというカスタム投稿タイプに、single-shop.phpというテンプレートを作ればそれが適用される)
single- [posttype].phpが無ければsingle.php、どちらも無ければindex.phpが使われる。
テンプレートの種類と優先順位についてはこちら:
WordPress「テンプレート」の優先順位 | 超初心者のサーバー移転とドメイン移管&ついでにWordPressも!
「カスタム投稿タイプ」とは…
WordPressは、デフォルトで2つの投稿タイプ(post_type)がある。
・投稿(ブログのような、時系列で並べたりカテゴリやタグで分類できる記事。post_typeは「post」)
・固定ページ(カテゴリやタグは付けられない。ページの親子関係を指定できる。post_typeは「page」)
コレら以外に、自分で好きな投稿タイプを追加できる。それがカスタム投稿タイプ。post_typeは「好きな名前」
★例えば、ショップとか製品情報など、違うテンプレートで表示したいモノがある時に使うと便利。
★テンプレートでの表示でなく、固定ページの中にパーツとして表示する事もできる。
★「カスタム投稿タイプ」は、カテゴリやタグで分類できないが「カスタムタクソノミー」で分類できる。また、時系列で並べられるし、ページの親子関係も指定できる。
「カスタムタクソノミー」とは…
WordPressにデフォルトで備わっている「カテゴリ」「タグ」のような分類を、自分で好きな名前で追加できる。これがカスタムタクソノミー。
★「カスタムタクソノミー」は、固定ページや投稿など全てのポストタイプに使える(どれか1つにヒモ付けされる)。
★「カスタム投稿タイプ」「カスタムタクソノミー」は、プラグイン Custom Post Type UI で簡単に追加できる。
記事の本文部分をループにする
home.phpをコピーし、ファイル名をsingle.phpに変更したら、
single.php内のメインコンテンツ部分に投稿記事を表示するわけなので、ここを編集。
(この他のheader, sidebar, footerはパーツテンプレートに分割済み)
ここに便利なWordPressの「ループ」を仕込んで、管理画面で書いた投稿記事を表示させる。
ループの基本形
ループは、該当する記事があれば、あるだけ表示するという繰り返し処理のPHPソース。
シンプルなのにオートマティックなWordPressの仕様です。
single.phpの場合は、該当する記事は1コなので、1回しか繰り返さないけど、
アーカイブページ(カテゴリやタグの一覧ページとか)なら、該当する記事をあるだけ表示する。
ループの基本形はこんなかんじ。
<?php if (have_posts()) : //もしも該当する記事があれば、 while (have_posts()) : //記事があるだけ the_post(); //記事を表示する //★ここに記事を表示する部分のソースを書く endwhile; //whileを終了 else: //★ここに投稿がない場合の表示ソースを書く endif; //ループを終了 ?>
記事を表示する部分を書いた具体例は、ざっとこんなかんじ。
<?php if (have_posts()) : while (have_posts()) : the_post(); //例えば下記のように、カテゴリによってdivのクラス名を変えたりできる //投稿がカテゴリ「1」に属していれば、CSSクラス"post-cat-one"のdivを、 //それ以外なら、CSSクラス"post"のdivを表示 if (in_category('1')) { ?> <div class="post-cat-one"> <?php } else{ ?> <div class="post"> <?php } ?> //タイトルとパーマリンクを表示 <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> //日時を表示 <small><?php the_time('Y年n月j日'); ?></small> //カテゴリをカンマ区切りで表示 <p class="postmetadata"><?php the_category(', '); ?></p> //投稿本文を表示 <div class="entry"><?php the_content(); ?></div> </div> //最初のdiv(クラス名post-cat-oneかpost)を閉じ <?php endwhile; else: ?> //whileを終了し、投稿がないなら以下を表示 <p>記事が見つかりませんでした。</p> <?php endif; ?>
記事本文を出力するテンプレートタグは「the_content()」(上のソースの18行目)。
管理画面で書いた記事は、このテンプレートタグでそっくりそのまま出力される。
上のソースはWordPress公式codexを参考にしました:ループ-WordPress Codex 日本語版
ループにパーツテンプレートを埋め込む
上のソースのように、ループのソース内に投稿記事表示用のソースを書いても良いが、
レイアウトのためのdivやp, imgなどを仕込むと、ソースが長く複雑になってしまう。
そこで、投稿記事表示部分だけ「パーツテンプレート」にして埋め込むほうが、スッキリするし、あとの編集が楽だ。
このブログでは「content.php」を別に作って埋め込むことにした。
<?php if (have_posts()) : while (have_posts()) : the_post(); get_template_part('content'); endwhile; endif; ?>
elseは省略。投稿記事が「無い」ってことは無いから。
(single.phpは投稿記事の表示だけだから。アーカイブや検索結果でループを使う時は elseは必要)
パーツテンプレートに関してはこちら:
index.phpをパーツテンプレートに分割する [WordPressテーマ作成の手順3] | *Web Design 覚え書き*
パーツテンプレートcontent.phpを作る
パーツテンプレートcontent.phpを作っていく。
まず、1番最初にHTMLファイルを作った中の、投稿ページ用レイアウト「single.html」をコピーして「content.php」という名前に書き換える。
このファイルの、投稿記事表示部分以外を全部削除する。
single.phpで記述する外側のボックス(<article>〜</article>など)が重複しないように、その中に入るモノだけ残す。
要するに、上のソースの5行目「get_template_part(‘content’);」のところに入れたいものだけを残すのね。
あとは、記事の日付・カテゴリ・タイトル・アイキャッチ画像・本文などを「テンプレートタグ」に書き換えるだけでOK。(最初にキチンと投稿用のレイアウト(single.html)を作っておけば、CSS指定も済んでおり、コレだけでOKなわけ。何事も最初の計画が肝心ですw)
<div class="col-full"> <div class="wrap-col"> <article class="postBox"> <div class="metaData clearfix"> <p id="iconDate"><img src="<?php bloginfo('template_url');?>/images/icon_dat_wht.png"/><?php the_time('Y年n月j日'); ?></p> <p id="iconCat"><img src="<?php bloginfo('template_url');?>/images/icon_cat_wht.png"/><?php $cat = get_the_category(); $cat = $cat[0]; $cat_name = $cat->cat_name; echo $cat_name; ?></p> </div><!-- ^ .metaData END--> <div class="entry_heading clearfix"> <div class="col-1-3"><?php the_post_thumbnail(); ?></div> <div class="col-2-3"><h1><?php the_title();?></h1></div> </div><!-- ^ .entry_heading END--> <div class="entry_body"><?php the_content();?></div> <div class="entry_body_bottom"></div> </article><!-- ^ .postBox END--> </div><!-- ^ .wrap-col END--> </div><!-- ^ .col-full END-->
それぞれの「テンプレートタグ」は、home.phpを作った時のモノとほぼ同じ。
(参考:トップページ用テンプレートhome.phpを作る [WordPressテーマ作成の手順8])
もちろん、レイアウトはCSSで大幅に変えている。
1つだけ、home.phpと違うテンプレートタグは、
抜粋記事のテンプレートタグ(the_excerpt())ではなく、
記事本文表示のテンプレートタグ(the_content())を使っていること(12行目)。
なお、上記ソースの div.col-full, div.wrap-col(1〜2と15〜16行目)は、本ブログのグリッドシステムのため。
投稿ページ間のリンクを表示する
content.phpができたので、single.phpで投稿記事が表示できるようになった。
ここでもう1つ、WordPressには投稿記事の「隣接記事へのリンク」をさせる便利で素敵なテンプレートタグがあるので、content.phpに追加しておく。
previous_post_link()」で前の記事(時系列的に1つ過去の記事)へ
next_post_link()」で次の記事(時系列的に1つ未来の記事)へ
リンクする。
「previous = 過去」「next = 未来」ってこと(普通ですな。いつも戸惑うけど…w)。
このテンプレートタグは必ずループ内で使う。じゃないと何も起こらない。
(今の状況では、single.phpのループ内に仕込まれているパーツテンプレートcontent.phpに書くからOKというわけ)
*上の図は、この時点で最新記事の表示なので「次の記事(未来の記事)」はまだ無いので空欄になっている。
本ブログの、上の図の部分のソースはこんなかんじ。
<div class="col-full"> <div class="clearfix"></div> <div class="wrap-col"> <nav class="adjacent_post_links clearfix"> <div class="col-1-2"> <div class="previous"><?php previous_post_link('%link', '%title'); ?></div> </div><!-- ^ .col-1-2 END--> <div class="col-1-2"> <div class="next"><?php next_post_link('%link', '%title'); ?></div> </div><!-- ^ .col-1-2 END--> </nav><!-- ^ .adjacent_post_links END--> </div><!-- ^ .wrap-col END--> </div><!-- ^ .col-full END-->
上記ソースの div.col-full, div.wrap-col, div.col-1-2 は、本ブログのグリッドシステムによるものです。
previous_post_link()
previous_post_link() の ()内の引数を省略すると、「アンギュラークウォート (<<) 」が付いたテキスト「<< 前の記事へ」が表示され、そのページへのリンクがつく。コレがデフォルト形。
引数を使って指定する場合、引数は次の5個。「,(カンマ)」で区切って使う。
previous_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy );
- $format
リンク部分のフォーマット。デフォルトは ‘%link’ のみ(下の$link(記事タイトル)を表示)。
‘<strong>%link</strong>’ ’Go to %link’ '<img src="arrow.png"> %link’ などと指定できる。 - $link
リンクのテキスト。デフォルトは ‘%title’ で記事のタイトル。
‘1つ前の記事へGO!’ などと好きな文言に指定できる。 - $in_same_term
コレだけはBoolean型(trueかfalse)。同じカテゴリーの記事に限定するかどうか。デフォルトは false。 - $excluded_terms
表示させたくない(除外する)記事のカテゴリID。複数指定はカンマで区切る(例 ‘1, 5, 15’) - $taxonomy
$in_same_term が true のときだけ使える。タクソノミーを表示。デフォルトは ‘category’
例えばこんなかんじで使用。
<?php previous_post_link('%link', '%title'); ?>
<?php previous_post_link('%link', 'このカテゴリでの前の記事へ', true, '1,8'); ?>
参考サイト:テンプレートタグ/previous post link-WordPress Codex 日本語版
next_post_link()
next_post_link() の ()内の引数を省略すると、「アンギュラークウォート (>>) 」が付いたテキスト「次の記事へ >>」が表示され、そのページへのリンクがつく。コレがデフォルト形。
あとは、previous_post_link() とまったく同じ仕様。
ただし、「向き」というものがあるので、CSSで右詰めにするとか、見やすい工夫は必要ね。
参考サイト:テンプレートタグ/next post link-WordPress Codex 日本語版
single.phpのその後の経過はコチラ
今回はsingle.phpを初めて作り、記事本文と、投稿ページ間のリンクを作った。
このあと、さらにsingle.phpに
・関連記事を表示させる
・コメント欄をつける
・Google広告を表示する
といった追加をして完成させる。(記事をアップ次第、順次リンクを貼っていきます)
Leave a Comment