ここはちょっと見せられない

ぜったいぜったい見せられない

category/archive.php の中で query_posts とか使って posts_per_page の指定はできない

http://d.hatena.ne.jp/ohesotori/20130906/1378457264

↑これとは別の話。

wordpress の表示設定のところで1ページのデフォルト表示件数を設定するけれど、アーカイブページのテンプレート側で posts_per_page を指定したってうまくいかない。
WPがGETリクエストを受け取った時に、どのテンプレートにするか判定する処理をする。
どうやら、投稿だと判断するも、該当するページ数を表示するほど投稿件数があるかどうかを見て、そのページ数に足る件数がなければ404エラーを返してしまう。

つまり、たとえば、20件中、1ページ当たり5件表示して、4ページ目までは投稿があるから見れるだけど、5ページ目以上は投稿が足りないから、表示ページ該当なしと判断する。投稿がありません、ではなく404。これは結構いや。

で、テンプレート側でいくらページ内表示件数を触ったところで、テンプレート判定の時に、404になっちゃって、アーカイブのテンプレート見てくれないしどうしようもないとなる。

再現する方法。
1:
[設定]->[表示]
にて、ページ内デフォルト表示件数を100件くらいにしておく。
2:
アーカイブに表示させる記事を20件くらい登録しておく。
3:
category.php で、query_posts($query_string . "&posts_per_page=5") とか書いて、
http://example com/category//page/2/

といった具合にGETリクエストを出すと、デフォルトが100件で、投稿が20件しかないから、すでに2ページ目が存在しなくて404行き。

まあ理由はだいたい分かったので、下記サイトを参考にしてみた。
http://wordpress.org/support/topic/pagination-in-custom-query-for-categoryphp-not-working
ここらへんに書いてあるアクションフックを仕掛ける。

add_action( 'parse_query', 'category_posts_per_page', 10, 1 );
function category_posts_per_page( $q_obj ) {
	if( is_category() )
		$q_obj->query_vars['posts_per_page'] = 1; // Example value
}

そもそも、テンプレート内でページ件数触るのは間違いだろうから、この方法が正しいんだろうな。もちろん、デフォルト設定を全部共通で使えるんならそれでいいけど、投稿の種類によっては、件数変えたいわけで、融通利かせたい。

ほんとなら、category.php の中で、記事がありません、っての出すのが理想的だと思うので、404が出るのはバグだと思うんだけど、思想の違いかもしれない。わかんないわ。

補足。

つまり、have_posts は false だけど、テンプレートは category.php もしくは archive.php のままが良い、ということ。