HOME > WordPress > ループで記事一覧を表示する(メインループとサブループ)

ループで記事一覧を表示する(メインループとサブループ)

記事一覧を表示するときに使う「ループ」についての備忘録。

メインループとサブループ

ループで記事一覧を表示する。WordPressのテーマ作りで何度も使ってきたこの「ループ」。コピペだけで対応していると、幾通りかの書き方の違いや使いどころがわからないままで不具合を出してしまう場合も。

「メインループ」と「サブループ」という二つの「ループ」を知ったのを機に「ループ」について少し確認した。

メインループ

まず「メインループ」。通常の投稿を表示するために使うループで、1つのテンプレートにつき一つ。

<ul>
<?php while (have_posts()): the_post(); ?>
	<li>
	<h2><?php the_title(); ?></h2>
	<?php the_content(); ?>
	</li>
<?php endwhile; ?>
</ul>

このループはシンプルで何の条件もないけれど、single.phpでは表示している投稿の内容だけを表示するし、category.phpでは表示しているカテゴリーに属する記事だけを一覧表示する(表示件数は「ダッシュボード>設定>表示設定」で指定した件数)。

なぜならURLによるリクエストに基づくクエリがテンプレートの読み込みより前に実行されるものだから。WordPressであらかじめ決められている内容が用意されて、テンプレートの読み込み時にはその内容だけを取得して表示される、ということかな。だからサブループと違ってリセットする必要はない。

投稿が無い場合もあるなら、投稿の有無で条件分岐してあげる。
<?php if (have_posts()): ?>【上記処理】<?php else: ?>【投稿が無い場合の処理】<?php endif; ?>

サブループ

サブループはメインループとは別にループを作りたい時に使う。トップページで通常投稿一覧とは別に、でカスタム投稿タイプの投稿を表示する場合など。

サブループはクエリをリセットする(endwhile;のあとにwp_reset_postdata();と書く)必要がある。サブループはテーマのテンプレートやプラグインのファイルの中で実行されるので、メインクエリを上書きしており、クエリをリセットして上書きされたメインクエリを復元してやらないと、テンプレートタグが当該投稿のメインクエリを使えないままになってしまうから。
※メインクエリの挙動がおかしい?と思った時は、サブループのクエリのリセット忘れがないかチェックするとよいかも。

以下、WP_Queryを使ったサブループ。

<?php
$args = array( 
	'post_type' => 'カスタム投稿タイプname'
);
$the_query = new WP_Query($args);
while ($the_query->have_posts()):
$the_query->the_post(); ?>
	<li>
	<h2><?php the_title(); ?></h2>
	<?php the_content(); ?>
	</li>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>

投稿が無い場合もあるなら、投稿の有無で条件分岐してあげることになるのはメインループと同じだが、書き方がちょっと違うので要注意。
<?php if($the_query->have_posts()): ?>【上記処理】<?php else: ?>【投稿が無い場合の処理】<?php endif; ?>
当たり前だが、if~は$the_queryの後、whileの前に入れる。それとこの書き方の場合、wp_reset_postdata();はendwhile;の後、else:の前でOK。

<?php
$args = array( 
	'post_type' => 'カスタム投稿タイプname'
); ?>
<?php 
$the_query = new WP_Query($args);
if($the_query->have_posts()): ?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
	<li>
	<h2><?php the_title(); ?></h2>
	<?php the_content(); ?>
	</li>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 【投稿が無い場合の処理】 -->
<?php endif; ?>

実装ケース例

実装したケースの例をメモ。

  • カスタムタクソノミーのタームごとにカスタム投稿タイプの記事を一覧表示する場合で、タームごとのグループを(ターム名順でなく)任意の順で並べたい場合、タームで絞り込んだ記事一覧のループを、表示したいタームの数だけ繰り返し書いた。

表示する内容を制御するパラメーターの書き方

たとえば、1ページに含める投稿数を指定するパラメータposts_per_page

$the_query = new WP_Query( array( 'posts_per_page' => 3 ) );
<?php
$args = array( 
	'posts_per_page' => 3
);
$the_query = new WP_Query($args); ?>

より詳細なパラメーターは関数リファレンス/WP Query – WordPress Codex 日本語版を参照のこと。

参考サイト