IT女子のお気に入りフォルダ

管理人の備忘録と実践を兼ねた(出来るだけ)役に立つ情報を配信するブログです。

特定のカスタム投稿タイプのみアーカイブでの表示件数を変える

例えば、「新着情報(news)」「キャンペーン(campaign)」「ギャラリー(gallery)」といった具合にカスタム投稿タイプを複数設置していて、アーカイブでの表示件数を「新着情報」と「キャンペーン」は10件にして、「ギャラリー」だけは16件にしたい!
といった場合の対処方法です。

対象のカスタム投稿タイプのテンプレートファイルでquery_postsを使って表示件数をセットしなおす方法もあります。ちょっと前にそういった内容をご紹介させていただきました。

参考:WordPressでアーカイブ毎に表示件数を変える方法

が、functions.phpでpre_get_postsをフックする方法を知った今、こっちの方がスマートじゃないか!と思った次第であります。
テンプレートファイルに書く手法だと、変更したいテンプレートファイルすべてに記述が必要になっちゃうからね。

pre_get_postsをフックする

functions.phpに下記を追加します。
さっきの「ギャラリー」だけ16件にする場合の例です。

add_action('pre_get_posts', 'my_pre_get_posts');
function my_pre_get_posts($query) {
    if (!is_admin() && $query->is_main_query() && is_post_type_archive('gallery')) {
        $query->set('posts_per_page', 16);
    }
}

is_main_queryでメインクエリにだけ適用されます。(サイドバーとかget_postsとかしてたら、それらは対象外になります)
WordPress3.3から登場した関数だそうです。
!is_admin()は管理画面以外という意味。

3行目のif分の条件を変えれば、いろいろ応用できます。

特定のカスタム投稿タイプじゃなくて、月別アーカイブだけ変えてみようかなとかいう場合

if (!is_admin() && $query->is_main_query() && $query->is_month()) {

ここまできたら、表示件数だけじゃなく他の条件だって変えられることに気づかれたと思います。
3行目から始まるif文の中を書き換えます。

$query->set('posts_per_page', -1); //全件表示
$query->set('cat', -7); //カテゴリーIDが「7」だけ除く

$query->('パラメーター名', '内容');を指定すればよいということです。パラメーターはquery_postsのパラメーターと同じです。

じゃ、最後にちょっと複雑な条件の例として以下3つの条件を満たす記述を

条件1:フロントページでは通常の投稿とカスタム投稿タイプ(news)を表示
条件2:月別アーカイブではその月の全投稿を表示
条件3:カテゴリーアーカイブでは1ページあたり10件ずつ表示

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_front_page()) { //フロントページ
        $query->set('post_type', array('post', 'news')); //投稿とカスタム投稿タイプ(news)を表示
        return;
    }

    if ($query->is_month()) { //月別アーカイブ
        $query->set('posts_per_page', -1); //全件表示
        return;
    }

    if ($query->is_category()) { //カテゴリーアーカイブ
        $query->set('posts_per_page', 10); //10件ずつ表示
        return;
    }
}