WordPressの条件付きページ表示の方法

佐野

佐野 2014年10月15日

引き続き、WordPressのテーマの作成を行っております。
今回は、カテゴリ、ユーザー、月間ごとの記事の出力に関してをお話します。
まず、記事を出力する基本形として、「index.php」ファイルに以下のような記述を行います。

if ( have_posts() ) : ;
 while ( have_posts() ) : the_post();
get_template_part('loop');
endwhile;
 else :
 ?>
 <p>
 投稿が見つかりませんでした
 </p>
 <?php endif; ?>

最初のif ( have_posts() ) : ;の部分は、
表示する投稿が見つかった場合に走査する条件分岐となります。
もし投稿がなかった場合には、else :の行に遷移する事になります。
最後には、endif;で、if文の終了という事になります。
ここまでは、見た目は違うものの、従来のif文と同じですね。
細かくは調査していないのですが、おそらくはhave_posts()の部分で、
booleanか何かの形式で、投稿記事の有無を返しているのでしょう。

while ( have_posts() ) : the_post();の部分からループが始まり、
投稿記事が見つかった分だけループが行われます。
ループの終端は、今回の記述ではendwhile;となります。
get_template_part('loop');では、「loop.php」ファイルを呼び出します。
ループで表示される記事のテンプレートは、基本的には「loop.php」に作成するのが推奨されているようです。

<h2 class="entry_title"><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>
 <span>カテゴリ:<?php the_category(', ') ?></span>
 <span>投稿日:<?php echo get_the_date(); ?></span>
<div class="entry_data">
 <?php
 /*アイキャッチ画像*/
 the_post_thumbnail('thumbnail');
 ?>
 <p>
<?php /* 文字列制限をしたうえで、記事の内容を表示する場合 */
 echo mb_substr(strip_tags($post-> post_content),0,200).'...';
 ?>
 <a href="<?php the_permalink(); ?>"class="">続きを読む</a>
 </p>
 <?php
 ?>
 </div>
<div class="entry_separate">
 <?php the_author_posts_link(); /* ユーザー名とその投稿を表示するリンクを生成 */?>
 </div>

これで記事の一覧を表示する事ができます。
お気づきとは思いますが、真ん中あたりに
echo mb_substr(strip_tags($post-> post_content),0,200).'...';がありますが、
その上の行のコメントに記載しました通り、記事の文字数制限を行いつつ表示させるという方法を行っています。
今回は、記事の一部を並べて表示し、全文を読むには「続きを読む」で開くようにしたかったため、
このようにいたしました。

引数にもあるように、200文字まで表示するようになっています。
出力されるのは文字だけのようで、画像タグなどはスルーされるようです。
普通に記事全文を出したい場合は、the_content();を使えば表示されます。
記事の一覧表示が出来たところで、次にカテゴリや投稿者、月間別で記事を出力したいと思ったのですが、
ここでいくらか、つまづきました。

カテゴリ記事には「category.php」、投稿者別の記事表示には、「author.php」を作ればよいとの事ですが、
これらのファイルに、「loop.php」をテンプレートに、記事一覧を呼び出すような記述をしても、
すべての記事が出力されてしまいますし、
かと言って、いくら探しても、カテゴリ別や投稿者別に出力する関数が見つからない・・・
いや、そもそも関数自体がないのか? という発想も生まれました。

そこで思いついたのが、いっそ自分で条件を作るべきなのかという考えです。
そして着目したのがURLパラメータ。
カテゴリをクリックして遷移した画面では、「cat=1」のように、
カテゴリIDが「cat」に代入されているのがわかります。
同じように投稿者の場合は、「author=1」のようになっているはずです。

ややアナログな気もしなくもないのですが、
いっそPHPの関数でURLパラメータの値を取得し、それを記事の出力条件にしようという考えです。
じつは、ループ内で出力する記事を条件で限定するWordPressの関数は、あるのです。

query_posts('author=' .$_GET['author']);
このように、「query_posts()」関数の引数に、文字列で条件を指定する事で、
ループ内の記事を限定取得させる事が可能になります。

$_GET['author']は、PHP独自のグルーバル変数で、
配列に入れる文字列に応じたURLパラメータを取得できます。
厳密には、連想配列にURLパラメータの値が入っていると言ったほうが正しいでしょうか。
これで、投稿者ごとの記事出力が可能となります。

<div class="content">
 <?php
 query_posts('author=' .$_GET['author']);/* パラメータからユーザー番号を取得し、それを条件にする */
 if ( have_posts() ) : ;/* 投稿がある場合はここより下のものを表示する */
 while ( have_posts() ) : the_post();
get_template_part('loop');
endwhile;
 else :
 ?>
 <p>
 投稿が見つかりませんでした
 </p>
 <?php endif; ?>
<div class="navigation">
 <?php next_posts_link(trim(__('&laquo; 前へ', 'default'))) ?>
 <?php previous_posts_link(trim(__('次へ &raquo;', 'default'))) ?>
 </div>
 </div>

これの要領で、「query_posts()」の値を変更する事で、
カテゴリや月間ごとの記事出力も可能となります。
カテゴリ別の場合:query_posts('cat=' .$_GET['cat']);
月間の場合:query_posts('m=' .$_GET['m']);
カテゴリは「category」を略して「cat」。ネコではありません。
月間は「month」の頭文字の「m」なんですね。
もしこれを「y」や「d」などに変更すれば、年別や日別に取れるような気もします(まだ試していませんが)。

個人的には、この方法が推奨された方法かどうかは、わかりませんが、
ただ、WordPressの関数にそれが用意されていないという事は、
独自に定義する必要はなく、基礎の応用で可能であるという事を意味しているとも考えられます。

jQueryでも何でもそう、フレームワークを使用する場合、
全ての事をフレームワークで可能であるという事ではなく、基礎との併用が大事だという事を学びました。
むしろフレームワークは、難しいことを簡潔にする補助にすぎなく、
いきなりフレームワークから入っても、無理が生じるのは目に見えています。

しかし逆に、基礎の情報は探せばたくさん見つかるので、
フレームワーク独自の値か、基礎の方法で行うべきかどうかを理解できれば、
フレームワークを利用した開発に入る事も、決して悪くはないとも思います。
実際、WordPressのテーマ作成を本格的に行ってみて、
WordPressの構造や要素出力の方法のほかに、PHPの書き方のよい練習にもなった気もします。