WP_Query や get_posts を使ったサブループの投稿一覧表示方法

更新2023/11/18

TOPページに複数の投稿一覧を表示する、とあるカテゴリーのページに別のカテゴリー一覧の記事を表示させたい(メインクエリとは異なる投稿を表示させたい)場合は「サブループ」というものを使います。これはWordPressでサイトを作る時には押さえておきたい仕組みです。

サブループを作るときは、WP_Query クラスと get_posts 関数を使う2つの方法があります。これらの違いとそれぞれのループの作り方をご紹介します。

WordPressのループ

ループとは投稿を表示するための仕組みのことを指します。ページによってどの投稿を表示させるか、というのはデフォルトで決められています。

デフォルトの状態のループをメインループ、それ以外にカスタマイズして任意の投稿を取得したいときに使われるのがサブループです。

ここではメインループでは取得できない投稿を表示させたいときに使用するサブループの使い方をご紹介していきます。

WP_Query と get_postsの違いと使い分け

WP_Query はクラス、 get_posts はラッパー関数と呼ばれるもので、書き方やパラメータが一部異なります。また「取得できる情報量」も違います。

get_posts は内部で WP_Query を使用し、いろいろな条件を絞り込んで処理を簡単にしているものです。そのため WP_Query の方がいろいろな条件を指定できます。

複雑な条件を指定して情報を取得したい、後から仕様変更の可能性があって幅広く対応させられるようにしておきたい場合は WP_Query を使用した方が、書き直しの手間が省きやすく修正しやすいので無難かなと思います。単純にタイトル・コンテンツ・日付などよく使うものなら get_posts で十分対応できます。

自分にとって使いやすい方やループ内での表示のさせ方を考えながら使い分けていきましょう。

返り値・書き方の違い

  • 【WP_Query】→「オブジェクト」(記事情報 + ページ情報)
  • 【get_posts】→「配列」(記事情報のみ)

WP_Query は記事情報以外にページ情報があるので is_single() といった条件分岐が使えますが、get_posts では使えません。

ループの回し方も変わります。

  • 【WP_Query】→「while文でループ」
  • 【get_posts】→「foreach文でループ」

get_posts は、have_posts()the_post() といった記述を省けます。(少しコードがスッキリする)

最新の記事を何件か取得してタイトルと記事の一部内容だけ表示する、という場合には get_posts() で十分です。

「ループの途中で何か処理を追加したい」といったことや「記事データ以外に表示されているページそのものの情報も取得したい」場合などは WP_Query を使って対応します。

パラメータの違い

使えるパラメーターはほとんど同じですが、get_posts 特有のパラメータもあります。

get_posts で使えるパラメーターWP_Query のパラメーター
numberposts posts_per_page
category cat
includepost__in
exclude post__not_in

numberpostsとposts_per_pageの違い

numberpostsposts_per_page のエイリアス(別名)ですが、初期に取得する投稿数が異なります。このような違いがあることを知らないと、表示されない?!となってしまうことも…

  • numberposts は管理画面で設定する最大投稿数を取得。
  • posts_per_page は指定されている投稿全てを取得。

表示件数が思った通りにならない場合はチェックしてみてください。

WP_Query() を使った基本コード

WP_Query は、データベースから投稿データを取得するクラスです。get_posts より様々な条件指定ができます。

<?php
  // 取得したい投稿内容の条件を指定
  $args = array(
    'post_type' => 'my_posts',
    'posts_per_page' => 3,
    'cat' => '10',
    'no_found_rows' => true;
  );

  // オブジェクト取得
  $my_posts = new WP_Query($args);

  // ループの開始
  while ($my_posts->have_posts()):
    $my_posts->the_post();
?>
  <!-- 表示させたい投稿内容 -->
  <h1><?php the_title(); ?></h1>
  <div><?php the_content(); ?></div>

<!-- 投稿表示終了。メインクエリの値に戻す -->
<?php endwhile; wp_reset_postdata();?>

上記の11行目にあるコードで新しいクエリを設定して記事を取得しています。

$my_posts = new WP_Query($args);

引数にある $args は配列形式で設定するパラメータを指定します。
「どういった内容の記事を取得するか」ということをここで決めているわけです。

  $args = array(
    'post_type' => 'my_posts',
    'posts_per_page' => 3,
    'cat' => '10',
    'no_found_rows' => true,
  );

上記のコードでは以下に当てはまる記事を取得します。

  • 投稿タイプは「my_posts」
  • 表示する件数は「3件」
  • カテゴリーIDが「10」のもの
  • ページングを無効化

「ページングの無効化」についてはこの記事を参考に取り入れました。
WP_Query関数のno_found_rowsパラメータについて

指定のないパラメータは初期値が使われます。指定できるパラメータはたくさんあるので、取得したい条件があるときは参考にしましょう。
よく使うものはこの記事内でもまとめています。
#args(引数)によく使うものとその内容

投稿の表示条件を指定して新しいクエリを取得したら、ループを使用して出力します。このループがサブループです。

<?php  
  while ($my_posts->have_posts()):
    $my_posts->the_post();
?>
  <!-- 表示させたい投稿内容 -->
  <h1><?php the_title(); ?></h1>
  <div><?php the_content(); ?></div>

<!-- 投稿表示終了。メインクエリの値に戻す -->
<?php endwhile; wp_reset_postdata();?>

$my_posts-> という記述が追加される以外はメインループと同じ記述でOKです。

サブループの場合は wp_reset_postdata() をつけることをお忘れなく。
#サブループの後は wp_reset_postdata()

get_posts() を使った基本コード

get_posts() の返り値は「クエリにマッチした投稿の配列」です。
関数内部では WP_Query() が使われていて、よりシンプルな値を返します。

WP_Query() はwhile文でしたが、get_posts() はforeach文を使います。

<?php
  // 取得したい投稿内容
  $args = array(
    'post_type' => 'my_posts',
    'posts_per_page' => 3,
    'category' => '10',
    'no_found_rows' => true,
  );

  // クエリオブジェクト取得
  $my_posts = get_posts($args);

  // ループの開始
  foreach ($my_posts as $val):
    $title = $val->post_title;
    $content = $val->post_content;
?>
  <h1><?php echo $title; ?></h1>
  <div><?php echo $content; ?></div>

<?php endforeach; ?>

get_posts() を使った場合、上記の記述では the_title() といった出力関数が使用できませんが、setup_postdata() を追加することで使えるようになります。

setup_postdata() で出力関数を使えるようにする

setup_postdata() はデータをセットします。
グローバルの $post を書き換えて the_title() などWP_Queryのメソッドが使えるようになります。

逆にこの記述がないと the_title() といった出力関数が使えないので、覚えておくと便利です。

<?php
  foreach ($my_posts as $val):
    global $post;
    $post = $val;
    // ↑ $valが$postに入る
    setup_postdata($post);
  // ↑ $valのデータをセットする
?>
  <h1><?php the_title(); ?></h1>
  <div><?php the_content(); ?></div>

<?php endforeach; wp_reset_postdata();?>

setup_postdata() を使った時は、wp_reset_postdata() でループをリセットすることをお忘れなく。

【PR】

プログラミング言語の人気オンラインコース

サブループの後は wp_reset_postdata()

サブループはメインクエリを変更しているため、サブループ後にメインクエリの内容を表示させる、他のサブループを使うといった場合にはリセットする必要があります。
そうしないと意図した投稿が表示されません。

サブループの後にメインクエリのデータを使わないのであれば、必ず必要なものではありません。ですが、思わぬところでメインクエリのデータが必要だったりもします。

条件分岐のコードがうまく動作しなかったりするので、セットで付けるくせをつけていた方がエラーの発生を抑えられます。

一旦ループを終了して再度同じサブループを回す

wp_reset_postdata() は投稿をリセットしてメインクエリの状態に戻しますが、サブループを一旦終了して再度サブループを回したい時にこの関数を使うともう一度同じ設定を書かなくてはならないので手間です。

同じサブループでもう一度まわしたい時はこのように書きます。

endwhile;
$the_query->reset_postdata();
//この後にもう一度 $the_query->have_post() で始められる

覚えておきたいパラメーター

基本的なサブループの作り方がわかれば、あとは「どういった投稿を表示させるか」という指定の部分をカスタマイズしていくのが主となります。どのような設定があるのかを知っていると多彩な表示方法ができるようになります。

そこで覚えておきたいのがパラメーターです。指定できるものがたくさんあって、全てを使いこなすのはなかなか大変ですが、いくつかよく使うものをまとめていきます。

$args = array(
  'post_type' => 'my_posts',
  'posts_per_page' => 3,
  'cat' => '10',
  'order' => 'ASC',
  'orderby' => 'modified',
);

‘post_type’ : 投稿タイプの指定

投稿タイプを指定します。デフォルトの値は ‘post’ なので、固定ページやカスタム投稿タイプの一覧を取得したいときに使用します。

通常の投稿‘post’
固定ページ‘page’
カスタム投稿タイプ‘作成した投稿タイプ名’

以下のように配列にして複数の投稿タイプを指定することもできます。

'post_type' => array('type01','type02'),

‘posts_per_page’ : 1ページに表示させる投稿数

1ページあたりに表示させたい最大投稿数を指定します。全件表示させたい場合は、’-1′ にします。

‘cat’, ‘category’, ‘category_name’ : カテゴリーから記事を指定する

カテゴリーを指定したい場合に使用するのがこれらのパラメーターです。使用するループのコードや値の指定方法が異なるので覚えておきましょう。
私は WP_Query でも get_posts でも使え、指定しやすい(IDは覚えられないけどスラッグ名は覚えていることが多いので) category_name をよく使用します。

catWP_Query でも get_posts でも使用できる。
「カテゴリーID」を指定する。
categoryget_posts でのみ使用できる。こちらも「カテゴリーID」を指定
WP_Queryで使用しても設定したカテゴリーは表示されない。
category_nameWP_Query でも get_posts でも使用できる。
「カテゴリースラッグ」を指定する。

‘order’, ‘orderby’ : 投稿の並び順を指定する

記事一覧の表示順序を指定するために使用するのがこの2つです。

order降順(DESC)、昇順(ASC)のどちらかを指定。(初期値は 'DESC'
orderbyで設定した内容の昇順・降順が表示される。
orderby「どの順序で並び替えるか」を指定。2つ以上でも設定可。
'date' …投稿日の日付順(初期値)
'modified' …編集日の日付順
'rand' …ランダムな並び順

orderby にはもっとたくさんの種類があるので、必要な並び順が上記にない場合は以下も参考にしてみて下さい。

‘post_status’ : 投稿の表示状態を指定する

「公開」や「非公開」といった投稿の表示状態を指定して表示させるのが 'post_status' です。

初期値は「公開」ですが、WordPressにログインしているときは「非公開」の記事も含まれます。WordPressにあまり詳しくないクライアントさんから非公開記事も一覧に出てきているのですが。。。なんて言われてしまった時は 'post_status' => 'publish', を追加して、どの状態でも公開記事のみ表示されるようにしましょう。

ループが表示されない時に見直したいところ

正しいパラメーターを使用しているか、値が間違っていないか(idやスラッグは正しいか)を確認してみて下さい。パラメーターの区切りがちゃんとできていなかったり、カンマ「,」が抜けてしまっていたり、結構些細なミスで表示されないことも多いので、コードの書き方に間違いがないかも見直してみましょう。

ループに query_posts() は使わない

query_posts() というメインクエリを変更する関数があって、一昔前はこれを使っていました。このコードは「WordPressのコアコードの中だけで使われるもの」とされていて、テーマ内で使用するのは非推奨とされています。

予期しない動作やエラーが発生する可能性が高くなるため、もし記述があったらできる限り変更しましょう。

カテゴリー : WordPress

【広告】

0からWebサービスやHPを作る力をつけたい・副業で収入を増やしたい・独学ではなかなか難しい…そんな方へサブスク型のプログラミングスクール「FREEKS」

会社の転職先、フリーランスの案件探しに。

実務レベルのノーコード開発スキルが学べるプログラミングスクール「Swooo BootCanp」

TOPへ