046
ループを巻き戻して、もう一度ループを開始する
Library
一旦終了したWordPressループを巻き戻すには、rewind_posts()関数を使用します。たとえば、投稿の一覧を出力する前にタイトルだけの目次を作成したり、あるいはおすすめの記事を先に表示し、それ以外を後から表示したりというような用途に使えます。
| 用例 |
|
|---|---|
| 関連 | |
| Codex |
ループを巻き戻す
基本的なWordPressループは次のようになっています。
<?php if ( have_posts() ) : ?>
<?php while( have_posts() ) : the_post(); ?>
<!-- 1つの投稿に対する処理 -->
<?php endwhile; ?>
<?php endif; ?>the_post()によって投稿を1つずつ取り出して処理を行い、投稿がなくなったらwhile文を抜け、終了します。ループ終了後は、クエリによって取得した投稿がthe_post()によってすべて取り出されているので、このままでは同じループをもう一度繰り返すことはできません。
そこで、rewind_posts()を実行することで、一度終了したループを巻き戻します。
<!-- 1度目のループ -->
<?php if ( have_posts() ) : ?>
<?php while( have_posts() ) : the_post(); ?>
<!-- 1つの投稿に対する処理 -->
<?php endwhile; ?>
<?php endif; ?>
<?php rewind_posts(); ?>
<!-- 2度目のループ -->
<?php if ( have_posts() ) : ?>
<?php while( have_posts() ) : the_post(); ?>
<!-- 1つの投稿に対する処理 -->
<?php endwhile; ?>
<?php endif; ?>rewind_posts()が実行されていない場合、2度目のループは何も出力しません。これはhave_posts()がfalseのままなので、if文の中に入らないためです。
特定のカテゴリーに含まれる投稿を先に出力する
投稿の一覧を出力する際、あるカテゴリーに含まれる投稿を先に表示することを考えてみます。
投稿が特定のカテゴリーに含まれるかどうかを判定するには、in_category()を使用して判定します。
WordPress関数
in_category( $category, $post )
第2引数に与えられる投稿が、第1引数のカテゴリに含まれるかどうかを判定する。
$category | カテゴリーを指定。ID、名前、スラッグ、またはそれらの配列を渡す |
|---|---|
$post | 調べる対象となる投稿。指定しない場合は現在の投稿が自動的に使用される |
管理画面の[投稿]にある[カテゴリー]を開けば、正確な名前やスラッグを調べることができます(URLを見ればIDもわかります)。
このin_category()関数を使って次のように処理すれば、今回の目的を達成することができます。
- 1度目のループで、投稿が特定のカテゴリーに含まれていれば出力
- ループを巻き戻す
- 2度目のループで、投稿が特定のカテゴリーに含まれない場合のみ出力
この処理を簡単にコードで書くと、次のようになります。ここでは、カテゴリーのIDを9とします。
<?php
if ( have_posts() ) {
while( have_posts() ) {
the_post();
if( in_category( 9 ) ) {
?>
<!-- 9番のカテゴリーに含まれる記事に対する処理 -->
<div class="entry-in-9-category">
<header class="entry-header">
<?php the_title( '<h2><a href="' . get_the_permalink() . '">', '</a></h2>' ); ?>
</header>
<div class="entry-content">
<?php the_content(); ?>
</div>
</div>
<?php
}
}
}
rewind_posts();
if ( have_posts() ) {
while( have_posts() ) {
the_post();
if( ! in_category( 9 ) ) {
?>
<!-- 9番のカテゴリーに含まれない記事に対する処理 -->
<div class="entry-standard">
<header class="entry-header">
<?php the_title( '<h2><a href="' . get_the_permalink() . '">', '</a></h2>' ); ?>
</header>
<div class="entry-content">
<?php the_content(); ?>
</div>
</div>
<?php
}
}
}
?>最初のループでは5行目のif( in_category( 9 ) )により、IDが9のカテゴリーに属する投稿だけが出力されます。スタイルを分けたければ特別なクラス名を付けたWrapperで囲むこともできますね。
次に、22行目のrewind_posts()によってループを巻き戻し、再度ループを開始します。今度は27行目のif( ! in_category( 9 ) )によって、9番のカテゴリーに含まれない投稿のみが順次出力されていきます。
in_category()はあるのにin_tag()は存在しない
in_category()という関数があるのなら、in_tag()という関数があってもおかしくないような気もするのですが、存在しません。「カテゴリーの中に投稿が含まれている」という考え方は一般的ですが、「タグの中に投稿が含まれている」という考え方は違和感がありますね。タグの場合は投稿につけるもので、「投稿」が主体となります。実際has_tag()という関数が存在し、in_category()と似たような働きをします。実はhas_category()という関数も存在し、in_category()は中でhas_category()を呼んでいるだけですので、’in’のほうが特殊であることがわかります。また、has_category()もhas_tag()も、has_term()というより原始的な関数から派生しています。
ループを巻き戻す事ができるんですね!
今さらながら知りました
実務でかなり使えそうですね!