投稿記事を普通にループで取得したい時は下記のように書きますね。
<?php if ( have_posts() ) : ?> <?php while ( have_posts() ) : the_post(); ?> <div class="col-md-4"> <?php get_template_part('template-parts/loop', 'news'); ?> </div> <?php endwhile; ?> <?php endif; ?>
投稿した記事をループさせるのはWPに用意されているメインクエリを使用しますが、 下記のページのように投稿ページのサイドバーやページ下部に違うループを表示させたい場合があります。
メインクエリだけでこれを実現しようとすると、下記のようになります。
上記のような時、サイドバー用のクエリを独自に定義する必要があります。
1.WP_Queryを使ってクエリを定義する
例えば、sidebar-latests.phpにサイドバーの新着リストを作りたい場合
<?php $args = array( 'post_type' => 'post', //投稿記事だけを指定 'posts_per_page' => 5, //最新記事を5件表示 ); $the_query = new WP_Query( $args ); if ( $the_query->have_posts() ) : ?> <aside class="archive"> <h2 class="archive_title">最新記事</h2> <ul class="archive_list"> <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?> <li> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> </li> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </ul> </aside> <?php endif; ?>
1.どのようなクエリを作るか配列で指定する
$args = array( 'post_type' => 'post', //投稿記事だけを指定 'posts_per_page' => 5, //最新記事を5件表示 );
2.クエリを作成
new WP_Query(配列)を$the_queryという変数に格納する
$the_query = new WP_Query( $args );
3.have_posts()とthe_post()の前に$the_query->を付け加える
『if ( $the_query->have_posts() ) :』は『もしも、$the_queryの記事があるならば』という意味になります。
if ( $the_query->have_posts() ) : ?> <aside class="archive"> <h2 class="archive_title">最新記事</h2> <ul class="archive_list"> <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?> <li> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> </li> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </ul> </aside> <?php endif; ?>
4.WP_reset_postdata()で投稿データをリセットする
new WP_Query()を使うとWPのループで使用されている投稿データが変わってしまうため、リセットして元に戻す必要があります。 new WP_Queryを使って独自のループを作成した時は、wp_reset_postdata()でリセットします。
<?php endwhile; ?> <?php wp_reset_postdata(); ?>
特定のページだけ表示数を変えたいなど、pre_get_postsアクションフックでメインクエリを変更する
例えば、WPのメインクエリの表示件数はダッシュボードの表示設定で設定されています。
例えば、TOPページだけ表示件数を変更したい場合には、pre_get_postsアクションフックを使用します。
WPがクエリを取得する前に実行されるpre_get_postsアクションフックをfunctions.phpに記述する
/** * メインクエリの内容を変更する */ add_action( 'pre_get_posts', 'my_pre_get_posts' ); function my_pre_get_posts($query) { // 管理画面、メインクエリ以外には設定しない if ( is_admin() || ! $query->is_main_query() ){ return; } //トップページの場合 if ( $query->is_home() ) { $query->set( 'posts_per_page', 3 ); return; } }
1.クエリ取得前に関数を実行
pre_get_postsアクションフックを使い、my_pre_get_postsというユーザ定義の関数を実行
add_action( 'pre_get_posts', 'my_pre_get_posts' ); function my_pre_get_posts($query) { }
2.実行する関数を定義するmy_pre_get_posts
pre_get_postsは全てのクエリの実行前が対象になるので、管理画面のクエリも対象です。 is_admin()で管理画面かをチェックし、管理画面の場合はreturnで関数を終了します。
// 管理画面、メインクエリ以外には設定しない if ( is_admin() || ! $query->is_main_query() ){ return; }
今回の例は、メインクエリのみを対象にしているので、is_main_query()関数を使ってチェックして、条件分岐を行います。
- ! $query->is_main_query():メインクエリ以外の時
- $query->is_home():トップページの時
- $query->is_category():カテゴリーページの時
// 管理画面、メインクエリ以外には設定しない if ( is_admin() || ! $query->is_main_query() ){ return; } //トップページの場合 if ( $query->is_home() ) { $query->set( 'posts_per_page', 3 ); return; }
WP_Queryについて
WPのメインクエリも独自で作成したクエリもWP_Queryを使用しています。WP_QueryはWPがクエリをつくるときに使用されるクラスです。
WP_Queryにはさま様なパラメータがあり、setを使うことで値をセットできます。
$query->set( 'パラメーター', 値 ); //例:$query->set( 'posts_per_page', 3 );
例:TOPページにお知らせカテゴリーに属する記事を表示する
- category_name:カテゴリーを指定するパラメーター
- news:指定するカテゴリーのスラッグ名
if ( $query->is_home() ) { $query->set( 'category_name', 'news' ); return; }
例:カテゴリーページではページングを使わず、全て投稿記事を表示する
全ての投稿を表示する場合は、nopagingというパラメータを使用します。
if ( $query->is_category() ) { $query->set( 'nopaging', true ); return; }