blog ブログ

2022.05.06

WordPress メインループとサブループの書き方

WEB

asa

こんにちは 、asaです。
WordPress で投稿を表示するためのメインループとサブループの表示方法を解説します。

ループとは?

PHPのwhile文やforeach文などを使い、データベースに格納されている記事データ(ページタイトルや本文の内容)があれば、その分だけ取得し表示させるための処理を繰り返すプログラムです。
最新記事一覧やカテゴリー別記事一覧を表示したい時に必須の方法です。

ループには2種類ある

ループには、メインループサブループの2種類があります。
メインループは、投稿した記事をそのまま取得します。
サブループは、メインループとは別に、複数設置したい場合などに、またページに表示させる投稿数を変更したり、取得するカテゴリーを絞り込むなど、特定の条件を付け加えることができます。

メインループ

投稿した記事をそのまま一覧で表示したい時に使用します。
投稿や固定ページのテンプレートファイル内で使用することで、ページタイトルや本文の内容を表示することができます。

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
  //繰り返し表示させたい内容を記述
<?php endwhile; else : ?>
  //投稿が無い場合の処理

ループの解説

if文を使った条件分岐

<?php if (have_posts()) : ?>

have_posts()で投稿データがあるかどうかをチェックしています。

while文を使ったループ処理

<?php while (have_posts()) : the_post(); ?>
  //繰り返し表示させたい内容を記述
<?php endwhile; ?>

have_posts()を指定することで、投稿データが存在する間は処理を繰り返します。
while内が投稿1件分の表示を繰り返すループ処理の部分で、endwhile;までが1ループになり、the_post();は投稿データを1件取り出して表示させるための準備をしています。

投稿データが存在している→1件分の投稿記事を取り出す→ループの先頭に戻る→
投稿データが存在している→1件分の投稿記事を取り出す→ループの先頭に戻る…
投稿記事がある限り、最後まで繰り返し処理を実行させます。

投稿が1件もなかった場合のみ表示させるコンテンツを記述します。

<?php else : ?>
  //投稿が無い場合の処理
<?php endif; ?>

endif;if文による条件分岐を終了させる記述になります。

1ページに表示させたい投稿件数を変更する

表示件数は管理画面の「表示設定」>「1ページに表示する最大投稿数」の設定で変更することができます。
管理画面の設定に依存せず、表示件数を変えたい場合などは後述のサブループを利用します。

色々なパターンの記述例

投稿が無い時は何も表示させない

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
  //繰り返し表示させたい内容を記述
<?php endwhile; endif; ?>

ifとwhileの記述を分けた例

<?php if (have_posts()) : ?>
  //投稿があった場合のみ表示させる
<?php while (have_posts()) : the_post(); ?>
  //繰り返し表示させたい内容を記述
<?php endwhile; ?>
<?php else : ?>
  //投稿が無い場合の処理
<?php endif; ?>

サブループ

サブループは、メインループとは別に任意にループを追加したい時に使用します。
特定のカテゴリーやカスタム投稿を表示させたい、 表示件数や表示順を変更したいなどの条件を指定する時に使います。

<?php 
  $args = array(
    //ここに表示したい記事の条件を記述
  );
  $the_query = new WP_Query($args);
  if ($the_query->have_posts()) :
?>
  //投稿があった場合のみ表示させる
    <?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
  //繰り返し表示させたい内容を記述
    <?php endwhile; ?>
    <?php else : ?>
  //投稿が無い場合の処理
    <?php endif; wp_reset_postdata(); ?>

ループの解説

if文が始まる前に、取得したい投稿データの条件を指定しています。

<?php 
  $args = array(
    //ここに表示したい記事の条件を記述
    'post_type' => 'post', //投稿タイプのスラッグを指定
    'category_name' => 'news', //カテゴリーのスラッグがnewsのみの記事を指定
    'posts_per_page' => 3, //に表示したい記事を最大3件に指定
    'order' => 'DESC' //記事の順番をソート(降順)
    'orderby'=>'date' // 日付で並べる
  );
?>

連想配列を使い、array()の中に条件(パラメータ)を記述。
上記の例では5つの条件を指定しています。
「カテゴリースラッグが「news」かつ 投稿を1ページに最大3件まで 降順に 日付で表示」

WP_Query

WP_Queryは記事データやページ情報を取得するクラスです。

$the_query = new WP_Query($args);

WP_Queryクラスの引数に連想配列$argsをセットしています。

直接WP_Queryの引数に記述してもOKです

$args = new WP_Query(
  array(
    //ここに表示したい記事の条件を記述
    'post_type' => 'post', //投稿タイプのスラッグを指定
    'category_name' => 'news', //カテゴリーのスラッグがnewsのみの記事を指定
    'posts_per_page' => 3, //に表示したい記事を最大3件に指定
    'order' => 'DESC' //記事の順番をソート(降順)
    'orderby'=>'date' // 日付で並べる
  );
);

wp_reset_postdata();

サブループは反映させた投稿情報を最後にリセットしてメインループに戻す必要があります。そのため endwhile(ループの終わり) の後に wp_reset_postdata(ページ送り関数) を追加してループをリセットして直前のクエリーを復元します。

wp_reset_postdata();

必ず最後に記述しましょう。

the_query

メインループの方の記述に $the_query->を追加しています。

<?php 
  if ($the_query->have_posts()) :
  while ($the_query->have_posts()) : $the_query->the_post();
?>

パラメータを格納した変数を記述することにより、メインループをWP_Queryクラスで作成した条件のループに反映させることができます。

get_posts

<?php
  $args = array(
    'post_type' => 'post', //投稿タイプを指定(カスタム投稿の場合はその投稿名を記述)
    'category_name' => 'news', //カテゴリーのスラッグがnewsのみの記事を指定
    'posts_per_page' => 3, //に表示したい記事を最大3件に指定
    'post_status' => 'publish', //公開済みページのみ指定
    'order' => 'DESC' //記事の順番を降順に指定
    );
    $my_post = get_posts( $args );
  ?>
<?php
  foreach ( $my_post as $post ) :
  setup_postdata( $post );
?>
  <?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
    <article class="article">
      <a href="<?php the_permalink(); ?>">
        <time class="time"><?php the_time( 'Y/n/j' ); ?></time>
        <h3><?php the_title(); ?></h3>
      </a>
    </article>
  <?php endwhile; ?>
<?php else : ?>
  <p>まだ投稿がありません。
<?php endif; wp_reset_postdata(); ?>

色々なパターンの記述例

投稿が無い時は非表示にする

<?php
  $args = array(
  //ここに表示したい記事の条件を記述
  );
  $the_query = new WP_Query($args);
  if ($the_query->have_posts()) :
?>
  //投稿があった場合のみ表示させる見出しなどの要素があれば記述(記述しなくても可)
<?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
  //繰り返し表示させたい内容を記述
<?php endwhile; endif; wp_reset_postdata(); ?>

条件の設定例

<?php
  $args = array(
    //ここに表示したい記事の条件を記述
    'post_type' => 'post', //投稿タイプのスラッグを指定
    'category_name' => 'news', //カテゴリーのスラッグがnewsのみの記事を指定
    'posts_per_page' => 3, //表示したい記事を最大3件に指定
    'order' => 'DESC' //記事の順番をソート(降順)
    'orderby'=>'date' // 日付で並べる
  );
  $the_query = new WP_Query($args);
  if ($the_query->have_posts()) :
?>
  <?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
    <article class="article">
      <a href="<?php the_permalink(); ?>">
        <time class="time"><?php the_time( 'Y/n/j' ); ?></time>
        <h3><?php the_title(); ?></h3>
      </a>
    </article>
  <?php endwhile; ?>
<?php else : ?>
  <p>まだ投稿がありません。
<?php endif; wp_reset_postdata(); ?>

終わりに

このようにメインループとサブループ、両方とも使いこなせるようになれば同一ページ内に「新着記事」と「おすすめ記事」を別々のエリアに表示させることや、カテゴリーに紐づく記事一覧など高度な実装が可能になります。ぜひ参考にしていただければ幸いです。

posted article 投稿記事

  • 【CSS】カード型レイアウトは「flex」or「grid」どっちがいい?

    2024.06.15

    【CSS】カード型レイアウトは「flex」or「grid」どっちがいい?

    WEB
  • スライダーライブラリ「Splide」を使ってみた

    2024.04.10

    スライダーライブラリ「Splide」を使ってみた

    WEB
  • PHP7からPHP8へのバージョンアップでエラー発生?

    2024.01.30

    PHP7からPHP8へのバージョンアップでエラー発生?

    WEB
  • [初心者向け][CSS]flexbox3カラム配置+最後の行だけアイテム2つの時に左詰にするレイアウト

    2024.01.15

    [初心者向け][CSS]flexbox3カラム配置+最後の行だけアイテム2つの時に左詰にするレイアウト

    WEB
View more

contact お問い合わせ・ご相談

制作のご依頼や予算のお見積りなど、まずはお気軽にお問い合わせください。

contact