WordPressでquery_posts()により表示件数を変えたときのページ送りについて

wp-pagenaviプラグインを使用し、paginationしていたが、該当テンプレートでquery_posts()を使って表示件数を変更すると前ページ、次ページなどページ送りが狂っているようだ。

query_posts($query_string . '&posts_per_page=5');
if (have_posts()) :
    while(have_posts()) :
      the_post();
....

現象は以下のサイトと同様である。

WordPressでquery_postsを使ったページ送りでNot Foundになる件

解決方法としては上記サイトで書いているように、

  • 管理画面の「表示設定」->「1ページに表示する最大投稿数」で1に設定

することだが、これだとすべてのページが1件しか表示されなくなりそう。そこでなぜquery_posts()で制御できていないのか落ち着いて考えてみた。

  1. wp-includes/query.php のソースを見てると管理画面の最大投稿数はposts_per_pageがクエリに指定されてないときに設定するようでそれは一度きりみたいなので特に問題がなさそう。
  2. ということはテンプレートで指定したquery_posts()のposts_per_pageはDBへのselect時には反映されていないということになるけど、wp-includes/query.php ではそうはみえない。ちゃんとqueryで指定があればselect文に反映されるはず。
  3. いや、テンプレートで指定したquery_posts()の前に"通常の(最初に起動する)"query_posts()が動作してしまってそれが影響しているのではないか?

そんなふうに考えて以下のコードをテーマディレクトリのfunctions.phpに入れて検証してみた。
コードではカテゴリID=3の時にposts_per_pageを設定するように指定。

function change_posts_per_page() {
        global $wp_query;

        if (is_category() && $wp_query->query_vars['cat'] == 3) {
                $wp_query->query_vars['posts_per_page'] = 5;
        }
}
add_action('pre_get_posts', 'change_posts_per_page');

管理画面の最大投稿数が10(デフォルト)のままだが、上記コードでカテゴリIDが3のときだけ5ページごとページ送りできるようになった。