「posts_per_page => 5
にしたのに全部出る…バグか?」──そんな声を現場でよく聞きます。
しかし諸君、そのほとんどは WordPress の仕様通り に動いているだけだ! 原因を見抜けば、解決は一瞬である。
Contents
🧩 症状再現:5件だけ出したいのに全件表示
$args = [
'post_type' => 'news',
'posts_per_page' => 5,
];
$query = new WP_Query( $args );
本来なら 5 件だけ取得されるはずが、ページ上には 全投稿がズラッと表示。
そしてクエリオブジェクトの $query->found_posts
を見ると、期待通り 5 件ではなく全件数……。
🔍 真犯人:pre_get_posts
で main query を改変していた!
テーマやプラグインでよく見かける、下記のような pre_get_posts
フィルター。
add_action( 'pre_get_posts', function( $query ) {
// フロント & カスタム投稿アーカイブで件数変更
if ( ! is_admin() && $query->is_post_type_archive( 'news' ) ) {
$query->set( 'posts_per_page', -1 );
}
} );
もし $query->is_main_query()
をチェックしていないと、管理画面はもちろん、別途生成した WP_Query にまで影響してしまいます。
結果、先ほど生成したローカルクエリでも posts_per_page
が書き換えられ、LIMIT が無効化されていた──というわけだ。
🛠️ 解決策:3 ステップで再発防止
is_main_query()
を必ず併用if ( $query->is_main_query() && 条件 ) { ... }
- 管理画面と REST API を除外
if ( is_admin() || wp_doing_rest() ) { return; }
- WP_Query を使うときは
wp_reset_postdata()
で後始末
📖 チェックリスト(コピペ保存推奨)
- posts_per_page が想定外 →
pre_get_posts
を疑え - フィルター内で
is_main_query()
を忘れていないか - 開発テーマ・プラグインのカスタムループが
wp_reset_postdata()
しているか
🔧 ベストプラクティス:件数変更は functions.php
ではなく archive-*.php
側で制御
「ニュース一覧だけ 5 件にしたい」など明確な用途があるなら、テンプレートファイルでローカルクエリを発行したほうが安全です。親クエリを書き換えないので、他ページやプラグインへの副作用ゼロ!
/**
* archive-news.php
* "news" カスタム投稿を 5 件ずつページング表示するサンプル
*/
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$args = [
'post_type' => 'news',
'posts_per_page' => 5,
'paged' => $paged,
];
$news_query = new WP_Query( $args );
if ( $news_query->have_posts() ) :
while ( $news_query->have_posts() ) :
$news_query->the_post();
// ▼ ここで記事カードやタイトルを出力
get_template_part( 'template-parts/content', 'news' );
endwhile;
// ページネーション(例)
the_posts_pagination( [
'total' => $news_query->max_num_pages,
] );
wp_reset_postdata();
endif;
この方法ならpre_get_posts に頼らず、一覧レイアウトに合わせて件数やソート条件を自在にカスタムできます。
🧠 まとめ
posts_per_page
が効かない原因の多くはクエリ書き換え。- フィルターを使うなら
is_main_query()
で影響範囲を限定。 - ローカルクエリの後は
wp_reset_postdata()
を忘れずに。
🔥 団長のエール
設定が反映されないとき、我々はつい「WordPress のバグか?」と疑う。だが違う!
それは “仕様” を知らぬがゆえの 落とし穴 だ。
仕様を知れば恐れは消え、バグは味方に変わる。
戦え、エンジニア諸君!! 仕様の深淵を覗き込み、クエリを制する者となれ🔥