メモ:WordPressにおけるループ関係の備忘録(pre_get_posts、get_posts)

posts_photo

備忘録としていつも使う処理をちょっとメモしておこうと思います。

メインループに使うpre_get_posts

メインループのカスタマイズは非推奨になったquery_posts()の代わりにpre_get_postsを使います。
下記のコードをfunction.phpに追加することで、指定したページのメインループが設定した仕様になります。

function myPreGetPosts( $query ) {
  //管理画面とメインループ以外のところでの動作阻止
  if ( is_admin() || ! $query->is_main_query() ){
    return;
  }

  //ここでページごとの$queryをセットします。これはhomeなら。
  if ( $query -> is_home() ) {
    $query->set('posts_per_page', 15);
    $query->set( 'cat', '-1,-1347' ); // -をつけることで特定のカテゴリーの除外
  }

  /category一覧なら。
  if ( $query -> is_category() ) {
    $query->set('posts_per_page', 30);
  }

  /特定の固定ページなら。
  if ( $query -> is_page(5) ) {
    $query->set('posts_per_page', 20);
    $query->set( 'cat', '123' ); //特定のカテゴリーで絞り込み
  }
}
add_action('pre_get_posts','myPreGetPosts');

条件分岐と$query->setを組み合わせることで、必要に応じた取得を実現します。
$query->setは表示数とカテゴリーが大半かと思いますが、条件分岐は仕事によって色々使いそうです。なんとなく条件分岐のis_tag()とかis_year()とかいつか必要になりそう。

カスタムループに使うget_posts

こちらの表示数の制限とカテゴリー絞り込みは本当によく使います。

<?php
  $args = array(
    'posts_per_page'   => 5,
    'category'  => 2,
    'category_name'  => 'example',
    'year'  => 2017
  );
  $myposts = get_posts( $args );
  foreach ( $myposts as $post ) : setup_postdata( $post ); 
?>

<li>
  <a href="<?php the_permalink(); ?>">
    <div class="thumnail"><?php the_post_thumbnail('full'); ?></div>
    <div class="title"><span><?php the_title(); ?></span></div>
    <div class="date"><?php the_time('Y/n/j'); ?></div>
  </a>
</li>

<?php 
  endforeach;
  wp_reset_postdata();
?>

以下のサイトを参考にさせていただきました。
WordPressで押さえておきたい!get_posts,WP_Query,query_posts の違いと用例
pre_get_postsでメインクエリを制御する

エンジニアのためのWordPress開発入門