WordPress

WordPress メインループとサブループの表示方法を紹介

WordPress メインループとサブループの表示方法を紹介

WordPress で投稿を表示するためのメインループとサブループの表示方法を紹介します。
例えば、最新記事一覧やカテゴリー別記事一覧を表示したい時に便利な方法です。

ループは大きく分けてメインループとサブループの2つに分けられます。
主にこの記事ではサブループの表示方法をプッシュして紹介しています。

  1. メインループの表示方法
  2. サブループの表示方法
    1. 投稿の表示件数を指定する方法
    2. 投稿をターム別に絞り込む方法
    3. 特定の投稿を除外する方法
    4. 現在表示している投稿を除外する方法
    5. 投稿を昇順・降順などで指定する方法
    6. 表示している投稿と同じタームに分類されている投稿をランダムに表示する方法
    7. 投稿数を取得する方法
    8. カスタムフィールドの値で投稿をソートする方法
    9. 投稿タイプを複数指定する方法
    10. 投稿一覧に年の見出しを付ける方法
  3. 固定ページの内容をトップページに表示させる方法

メインループの表示方法

投稿を表示するためのループのことをメインループと呼びます。
投稿や固定ページのテンプレートファイル内で使用することで、ページタイトルや本文の内容を表示することができます。
例えば、投稿の内容を表示したい場合は、次のコードをテンプレートファイルに追加します。

<?php if (have_posts()): ?>
<?php while (have_posts()) : the_post(); ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
</div>
<?php endwhile; ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

ページタイトルや本文の内容を表示したい場合は、while以降に タイトルを表示するget_the_title() や、本文の内容を表示する the_content() を使うことで投稿内容を表示します。
投稿内容が必ずある場合はif文を省略することもできます。

<?php while (have_posts()): the_post(); ?>
<!-- 中略 -->
<?php endwhile; ?>

メインループで使用する $wp_query は一度しか呼び出すことができません。そのため、複数のループを表示するためには、rewind_posts() を呼び出してクエリーを再利用するか、新しいクエリーオブジェクトを生成する必要があります。

クエリーとは記事を表示するためのリクエストの塊と考えるとイメージしやすいと思います。
例えば、最新の記事を5件表示したい場合に、この希望をリクエストとしてまとめてシステムに渡すと、その内容に沿った記事情報を持ってきてくれるような感じです。初心者の方には難しいかもしれませんが、これが理解できると WordPress の表示に苦手意識はなくなるでしょう。

話を戻して、基本的には一つのテンプレート内で使用メインループは一つまで。
メインループとは別にループを複数設置したい場合は、次に紹介するサブループを使います。

サブループの表示方法

サブループは、メインループとは別にループを作りたい時に便利な方法です。
例えば、カスタム投稿タイプ Products の投稿を表示する場合は、次のコードをテンプレートファイルに追加します。

<?php
$args = array( 'post_type' => 'Products' ); // カスタム投稿タイプ Products
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
</div>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

サブループはメインループと違い、ループの終わりにクエリをリセットする必要があります。
そのため endwhile(ループの終わり) の後に wp_reset_postdata(ページ送り関数) を追加してループをリセットして直前のクエリーを復元します。

そもそも、メインループ(メインクエリ)とサブループ(二番目のクエリ)は次のように違いがあります。
メインループは、URL によるリクエストに基づいたクエリが、テンプレートが読み込まれる前に実行されるのに対して、サブループはテーマのテンプレートやプラグインのファイルの中で実行されます。そのため、サブループの実行後はサブループがクエリーを上書くためにメインクエリを復元してあげる必要があります。

投稿の表示件数を指定する方法

サブループの表示件数を制御する場合は posts_per_page を追加します。
例えば、投稿を5件だけ表示したい場合はパラメーター 'posts_per_page' => 5 を追加します。

<?php
$args = array(
'post_type' => 'Products', // 投稿タイプのスラッグを指定
'post_status' => 'publish', // 公開済の投稿を指定
'posts_per_page' => 5 // 投稿件数の指定
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

非公開の投稿を除外したい場合は 'post_status' => 'publish'publish 公開済の投稿を指定します。
全件表示したい場合はパラメーター 'posts_per_page' => -1 で、値を-1(全件表示)と指定します。

投稿をターム別に絞り込む方法

サブループの投稿をカスタム分類(タクソノミー) Products-cat のターム item1 別に絞り込む場合は tax_query を追加します。

<?php
$args = array(
'post_type' => 'Products', // 投稿タイプのスラッグを指定
'tax_query' => array(
array(
'taxonomy' => 'Products-cat', // タクソノミースラッグを指定
'field' => 'slug',
'terms' => 'item1', // タームスラッグを指定
)
)
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

特定のタームを除外する場合は、パラメーター 'operator' => 'NOT IN' を追加します。

<?php
$args = array(
'post_type' => 'Products', // 投稿タイプのスラッグを指定
'tax_query' => array(
array(
'taxonomy' => 'Products-cat', // タクソノミースラッグを指定
'field' => 'slug',
'terms' => 'item1', // タームスラッグを指定
'operator' => 'NOT IN' // 指定したタームを除外する
)
)
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

特定の投稿を除外する方法

サブループで特定の投稿を除外する場合は、パラメーター post__not_in を追加します。
例えば、投稿ID 11,22,33,44,55 を除外する場合は次のように指定します。

<?php
$args = array(
'post_type' => 'Products', // 投稿タイプのスラッグを指定
'post__not_in' => array( 11,22,33,44,55 )
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

現在表示している投稿を除外する方法

現在表示しているページを除外する場合は、パラメーター post__not_in$post->ID を指定します。

<?php
$args = array(
'post_type' => 'Products', // 投稿タイプのスラッグを指定
'post__not_in' => array($post->ID)
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

投稿を昇順・降順などで指定する方法

サブループの投稿を昇順(最低から最高へ)で並び変える場合は、パラメーター 'order' => 'ASC' を追加します。

<?php
$args = array(
'post_type' => 'Products', // 投稿タイプのスラッグを指定
'order' => 'ASC'
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

サブループの投稿を降順(最高から最低へ)で並び変える場合は、パラメーター 'order' => 'DESC' に変更します。

表示している投稿と同じタームに分類されている投稿をランダムに表示する方法

現在表示している投稿を除外して、同じタームに分類された投稿をランダムに表示する場合は get_the_terms を使用します。
この方法はタームを複数選択している場合には対応していません。
タームを複数選択している場合は WordPress 現在表示されている投稿と同じタームに分類された投稿を表示する方法をご覧ください。

<?php
$terms = get_the_terms($post->ID,'products-cat');
foreach( $terms as $term ) {
$term_slug = $term->slug; // 現在表示している投稿に属しているタームを取得
}
$args = array(
'post_type' => 'Products', // カスタム投稿タイプ Products
'post__not_in' => array($post->ID), // 現在表示している投稿を除外
'posts_per_page' => 9, // 表示件数9件
'orderby' => 'rand', // ランダム
'tax_query' => array( // タクソノミーの指定
array(
'taxonomy' => 'products-cat',
'field' => 'slug',
'terms' => $term_slug, // 取得したタームを指定
))
); $the_query = new WP_Query($args); if($the_query->have_posts()): ?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

WordPress のプラグイン Anything Order など、並び順変更プラグインを使用して投稿の並べ替えを行うと、プラグインのバージョンによっては、クエリとテンプレートの記述がぶつかって表示がランダムにならない場合があります。その場合は、プラグインのアップデートやプラグインの停止などで対処しましょう。

投稿数を取得する方法

サブループで指定したクエリから投稿数を取得する場合は、 $the_query->found_posts を使って取得します。

<?php echo $the_query->found_posts; ?>

カスタムフィールドの値で投稿をソートする方法

カスタムフィールドの値で投稿をソートする場合は meta_query を使用します。
例えば、カスタム投稿タイプ Products のカスタムフィールド ホゲホゲ に、フガフガ が入力されている場合の投稿を表示するには、次のコードをテンプレートファイルに追加します。

<?php // カスタムフィールドの値で投稿をソートする
$args = array(
'post_type' => 'Products', // 投稿タイプを指定
'posts_per_page' => 5, // 投稿の表示件数を指定
'meta_query' => array( // カスタムフィールドを指定
array(
'key' => 'ホゲホゲ', // フィールド名の指定
'value' => 'フガフガ', // 値の指定
'compare' => 'LIKE' // フィールド値の部分一致
)
)
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

ソートの詳しい情報はWordPress 投稿をカスタムフィールドの値でソートして一覧を取得する方法をご覧ください。

投稿タイプを複数指定する方法

サブループで投稿タイプを複数指定する場合は post_typearray を使用して、ポストタイプのスラッグを複数指定します。
例えば、カスタム投稿タイプのスラッグ information と Products の二つを混ぜて、そこから最新の投稿を5件表示する場合は、次のコードをテンプレートファイルに追加します。

<?php
$args = array(
'post_type' => array('information','Products'), // 投稿タイプを複数指定
'posts_per_page' => 5 // 投稿件数を指定
);
$the_query = new WP_Query($args); if($the_query->have_posts()):
?>
<?php while ($the_query->have_posts()): $the_query->the_post(); ?>
<a href="<?php the_permalink(); ?>"><?php echo get_the_title(); ?></a>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>

投稿一覧に年の見出しを付ける方法

投稿一覧に年の見出しを付ける方法を紹介します。
例えば、投稿タイプのスラッグが news の場合、投稿一覧に年毎の見出しを表示するには、次のコードを追加します。

<?php
$post_year = false; // 年の比較用変数の初期化
// サブループの準備
$args = array(
'post_type' => 'news', // 投稿タイプのスラッグを指定
'post_status' => 'publish', // 公開済の投稿を指定
'posts_per_page' => -1, // 投稿件数の指定
'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(); ?>
<?php // 年を表示、続く投稿が同一年なら表示をスルー
if ( $post_year != get_post_time('Y') ) { // 比較の値と投稿年が異なる場合に年を表示
echo '<h2>'.get_post_time('Y年').'</h2>'; //投稿の年を表示
}
?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php echo get_the_date(); ?>
<?php the_permalink(); ?>
<?php echo get_the_title(); ?>
<?php the_content(); ?>
</div>
<?php
$post_year = get_post_time('Y'); // 年月の比較用の変数に今の投稿の年月を代入
endwhile;
?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<!-- 投稿が無い場合の処理 -->
<?php endif; ?>

表示に月も混ぜたい時は投稿一覧に年と月の見出しを付ける方法をご覧ください。

固定ページの内容をトップページに表示させる方法

トップページなどに固定ページの内容を表示したい時は post_type の指定を page_id に変更します。
例えば、固定ページのページIDが 123 の場合に、トップページにページID123のページを表示したい時は、次のコードをテンプレートファイルに追加します。

<?php $args = array( 'page_id' => 123 ); $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: endif; ?>
<?php wp_reset_postdata(); ?>

固定ページのIDは管理画面の固定ページの編集画面のURLから参照することができます。
ページIDの指定をページスラッグに変更したい時は page_idpagename に変更することで対応できます。

<?php$args = array( 'pagename' => 'products' ); $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: endif; ?>
<?php wp_reset_postdata(); ?>

まとめ

WordPress で投稿を表示するためのメインループとサブループの表示方法を紹介しました。
サブループの表示になれてくると、新着記事一覧やカテゴリーに紐づく記事一覧など、巷でよく見る記事一覧ページを簡単に作れるようになります。
最初は難しいかもしれませんが試行錯誤してチャレンジしてみましょう。

この記事をシェアする