【PHP】WordPressで記事一覧を取得する方法(投稿、固定ページ、カスタム投稿タイプを含む)
私はWordPressで記事一覧を取得するのは、もう慣れたもんですが、それでも細かい条件の指定方法などを結構忘れてて、よく調べたりします。
このページを訪れた諸兄らもそのような境遇ではなかろうか。
今回はWordPressで記事一覧を取得する方法をまとめました。
WordPressの記事一覧を取得するPHPの関数は3種類ある
まず、今回はWordPressのテーマ内でPHPを使って記事一覧を取得する方法を紹介するのですが、PHPで記事一覧を取得できる関数は3種類存在します。
- WP_Query
- get_posts
- query_posts(非推奨)
query_postsは非推奨になっていますが、残りのWP_Queryとget_postsはどちらを使っても構いません。
WP_Queryでの記事一覧の取得
<?php
$query_result = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
)); ?>
if ($query_result->have_posts()): ?>
<ul class="news_list">
<?php while($query_result->have_posts()): $query_result->the_post(); ?>
<li>
<a class="news_block" href="<?php the_permalink(); ?>">
<time><?php echo get_time('Y/m/d'); ?></time>
<?php echo get_the_title(); ?>
</a>
</li>
<?php endwhile; ?>
</ul>
<?php else: ?>
<?php // 条件に一致する記事が無かった場合 ?>
<p>現在掲載中のお知らせはありません。</p>
<?php endif; ?>
ちなみに、while~endwhile;の内部についてはテンプレート化するのがオススメです。
テンプレート化する場合は以下の通りです。
【new_list.php】
<?php
$query_result = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
)); ?>
if ($query_result->have_posts()): ?>
<ul class="news_list">
<?php while($query_result->have_posts()): $query_result->the_post(); ?>
<li><?php get_template_part('news_block'); ?></li>
<?php endwhile; ?>
</ul>
<?php else: ?>
<?php // 条件に一致する記事が無かった場合 ?>
<p>現在掲載中のお知らせはありません。</p>
<?php endif; ?>
【news_block.php】
<a class="news_block" href="<?php the_permalink(); ?>">
<time><?php echo get_time('Y/m/d'); ?></time>
<?php echo get_the_title(); ?>
</a>
「なぜテンプレート化するのか?」ですが、テンプレート化しておけば、再利用性が増します。
また、get_template_part()ってnews_block.php以外にnews_block-important.phpなどを作ると、別バージョンとして、get_template_part(‘news_block’, ‘impotant’);で呼び出せるようになるんです。便利~
しかも、WordPress5.5以降、テンプレートに変数を渡すことができるようになりました。
これ意外と知らない人が多いんですが、使いこなすとめちゃくちゃ便利です。
いつか詳しく説明します。
WP_Query・get_postsの引数(記事一覧の絞り込み条件)について
WP_Query・get_postsにはすんごいたくさんの条件設定ができます。
これを毎回忘れるんですよ。みんなもそうでしょ?
記事一覧取得の基本は以下のセットで良いかと思います。
<?php
$query_result = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
)); ?>
投稿・固定ページ・カスタム投稿タイプの取得
これらの切り替えにはpost_typeを変更します。
<?php
$query_result = new WP_Query(array(
'post_type' => 'post', // 投稿
'post_type' => 'page', // 固定ページ
'post_type' => 'works', // カスタム投稿タイプ(タクソノミー名が入ります)
)); ?>
公開状態を取得条件に指定する
デフォルトでは「公開済み」の記事しか取得しないのですが、例えばテストとして「公開済み」と「下書き」を表示したい場合などあるかと思います。
これらの条件も変更可能です。
<?php
$query_result = new WP_Query(array(
'post_status' => 'publish', // 公開済み
'post_status' => 'draft', // 下書き
'post_status' => array('publish', 'draft'), // 公開済みと下書きの両方を取得したい
)); ?>
投稿カテゴリーで絞り込みする
投稿をカテゴリーで絞り込む処理は本当に頻繁に使います。
これは忘れないようにしておきましょう。
そう、忘れないでください。これは【投稿】をカテゴリーで絞り込む方法なんです。
【タクソノミー】を絞り込みたい場合はまた別の方法があるんです。
<?php
$query_result = new WP_Query(array(
'post_type' => 'post', // 投稿カテゴリーの絞り込みなので
'cat' => 4, // カテゴリーID(整数値が入ります)
'cat' => get_category_by_slug('news')->cat_ID, // カテゴリースラッグからIDを取得して代入もできます
'category_name' => 'news', // 実はカテゴリースラッグでも指定できます
'category_name' => 'news, tips', // 複数のカテゴリースラッグを指定する場合
)); ?>
ほんとに多いので、徐々に追加していきます。ごめんなさい。
query_postsが非推奨になっている理由
query_postsが非推奨になっている理由としては、メインループを書き換えてしまうためです。
対して、WP_Queryとget_postsについてはサブループで動かすため、メインループを書き換えません。
メインループとサブループ
はて?メインループ?サブループ?という方は以下をご確認ください。
【メインループ】
<?php if (have_posts()): while (have_posts()): the_post(); ?>
<!-- 記事を表示するHTMLを記述 -->
<?php endwhile; endif; ?>
【サブループ】
<?php if ($query_result->have_posts()): while ($query_result->have_posts()): $query_result->the_post(); ?>
<!-- 記事を表示するHTMLを記述 -->
<?php endwhile; endif; ?>
この2つのコードは取得した記事一覧の情報にループ処理で1つアクセスしています。
こういう処理を『イテレータ』と呼ぶのですが、the_post();を呼ぶことで先頭から順番に記事情報を参照しています。
メインループとサブループの違いは関数をそのまま呼んでいるか、変数から呼んでいるかです。
変数($query_result)から呼んでいる場合(サブループの場合)、この変数($query_result)に記事一覧を代入したのだろうと考えられますよね?
では、メインループは何を参照しているのか・・・?
実はその点を問題視され、query_postsは非推奨となりました。
メインループっていうのは、ページを開いた時点で設定されている記事情報を参照しています。
例えば、category.phpでは、query_postsもWP_Queryもget_postsも使われていないのに、最初から上記のループが記述されています。
これはcategory.phpが参照される時は、何かのカテゴリーが参照された時なので、そのカテゴリーを含む記事一覧が自動的に取得されます。
これがメインループの記事情報です。
では、category.phpのメインループ内でquery_postsが使われた時、どうなると思いますか?
すごく簡単にどういう処理になるか説明すると、以下のようなループが存在するとして
<?php
$count = 12;
while ($count > 0) {
$count -= 1;
}
?>
途中でquery_postsを使うということは、以下のコードに近いことをしているということになります。
<?php
$count = 12;
while ($count > 0) {
$count -= 1;
$count = 62354; // 別のループを作りたいので、条件を再設定
while ($count % 3) {
$count = $count / 2;
}
}
?>
ループの途中で、ループの条件が書き換えられてしまうわけですから、こんなもんおかしくなりますよね?
これがquery_postsが非推奨となった理由です。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。