posts_per_pageがダッシュボードの設定よりも小さいときでも正しくページングさせる方法

posts_per_pageの値が「1ページに表示する最大投稿数」よりも小さいとページングが正しく動作せず、「ページが見つかりません。」と表示されてしまう場合があります。とりあえず解決コードを。例を3パターンあげていますので、適当なものをfunctions.phpに記述します。

// 例1 : カスタム投稿タイプが「products」のときに表示件数を「9」に設定
add_filter( 'parse_query', 'parse_query' );
function parse_query( $query ) {
	if ( get_query_var( 'post_type' ) == 'products' ) {
		$query->set( 'posts_per_page', 9 );
	}
}

// 例2 : カスタムタクソノミーが「products_category」のときに表示件数を「9」に設定
add_filter( 'parse_query', 'parse_query' );
function parse_query( $query ) {
	if ( get_query_var( 'products_category' ) ) {
		$query->set( 'posts_per_page', 9 );
	}
}

// 例3 : カスタム投稿タイプが「products」のとき、もしくはカスタムタクソノミーが「products_category」のときに表示件数を「9」に設定
add_filter( 'parse_query', 'parse_query' );
function parse_query( $query ) {
	if ( get_query_var( 'post_type' ) == 'products' ) || get_query_var( 'products_category' ) ) {
		$query->set( 'posts_per_page', 9 );
	}
}

以下で、原因など解説します。

状況

カスタム投稿のアーカイブページを作成し、そのページだけ表示件数をようと思いposts_per_pageを設定したところ、2ページ目を表示したときに「ページが見つかりません。」になってしまいました。状況は下記の通りです。

  • カスタム投稿タイプ「products」を作成
  • 「1ページに表示する最大投稿数」は10。
  • productsのアーカイブページのみ表示件数を9件にしたかったので、archive-products.phpの中に下記のコードを記述。
    <?php
    // archive-products.php
    // もとのクエリの表示件数だけを上書き
    query_posts( array_merge( $wp_query->query, array(
    	'posts_per_page' => 9
    ) ) );
    ?>
    
  • 登録されている記事数は10件。従って、ページングナビゲーションとして「1, 2」が表示される。
  • 2ページ目へのリンクをクリックすると「ページが見つかりません。」

pagedが何らかの影響で上手くきいていないのかと思い、query_postsを下記のように変更。

<?php
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
query_posts( array_merge( $wp_query->query, array(
	'posts_per_page' => 9,
	'paged' => $paged
) ) );
?>

が、状況はかわらず。pagedは固定ページでカスタム投稿のアーカイブを作る場合などに使用するもので、設定忘れの場合は「常に1ページ目が表示される」という現象が起こるはずなので、解決しないのも当たり前か。

posts_per_pageの値が「1ページに表示する最大投稿数」よりも小さいとページングが正しく動作しない!?

同じような現象の方いないかググってみたところ、どうやら「posts_per_pageの値が「1ページに表示する最大投稿数」よりも小さいとページングが正しく動作しない」というのは定説らしい。

カテゴリの一覧ページで似た状況になったことがあります。
posts_per_pageの値が、ダッシュボードの表示設定の「1ページに表示する最大投稿数」よりも少ない場合に発生するかもしれません。
お試しください~

WordPress › フォーラム » トップページを固定ページにしたらページ送りができません。

このパラメータを使う時の注意点ですが、WordPressでは、管理画面の「設定」の「表示設定」の「1ページに表示する最大投稿数」と干渉しますので、もしこのパラメータを利用する場合は、 「1ページに表示する最大投稿数」の値をposts_per_page=で指定する値より小さくする必要があります。

記事一覧を並び替えるquery_postsについて | たなブログ WordPress入門講座

「posts_per_pageの値が「1ページに表示する最大投稿数」よりも小さい」とダメなわけですから、解決方法として、「1ページに表示する最大投稿数を1にする」という方法が挙げられていました。そうすればposts_per_pageは必ず「1ページに表示する最大投稿数」より大きくなるわけだからページングはうまく動作するのでしょうが、どうにもダサい。他の一覧ページでもposts_per_pageを必ず指定しないといけなくなるし。

WordPressの動作を推測

ここで、WordPressの動作を推測してみました。恐らく下記のような動作になっているのではないかと。

  1. クエリを解析
  2. クエリをもとに利用するテンプレートを設定
  3. テンプレートで指定されたquery_postsを実行
  4. 表示

これで気づきました。気づきましたか?まず標準のクエリを解析し、それをもに、どのテンプレートを使おうかとWordPressが判断します。つまり、テンプレートが決定された段階ではquery_postsが実行されていないのです。

  1. クエリを解析(ここでは「1ページの最大投稿数 = 10」で判定)
  2. クエリをもとに利用するテンプレートを設定(登録されている件数は10件。(1)の設定より、2ページ目は存在しない。404ページをロード)
  3. テンプレートで指定されたquery_postsを実行(posts_per_pageで表示件数を9件に設定)
  4. 表示(404ページを表示)

ということで、テンプレートで件数設定をしようというのがそもそもの間違い。テンプレートの選択より前に件数の設定を実行すれば良い = functions.phpに記述すれば良いということです。

MW WP Form

MW WP Form はショートコードベースのフォームプラグインです。多くの機能を持っており、例えば、多くのバリデーションルール、問い合わせデータの保存、そしてグラフ機能集計などを使用することができます。

さらに詳しく
Habakiri

Habakiri

Bootstrap ベースのシンプルな WordPress テーマ。レスポンシブ、多くのカスタマイズ機能。圧縮された CSS・JS を使用する高速化対策。Microformats 対応。Sass、クラスベースの functions.php。

さらに詳しく
basis-stylus

Basis

軽量なレスポンシブ Stylus/CSS フレームワーク。Flexbox ベースのグリッドシステム、疎結合なコンポーネント、バーティカルリズム。

さらに詳しく