WordPressでページングが出来ない時はquery_postsではなくis_main_queryで解決だ!!

wordpress_page_404

WordPressを利用していると、沢山の問題にぶち当たります。それを解決していくのがまた勉強になって面白いんですが、今回は困った!ページングのお話です。

当ブログはトップページに通常のポストと共にカスタム投稿タイプを表示しています。初めから存在するテンプレート(index.php)のままだとカスタム投稿タイプを表示させることは出来ないので、特別に表示させてあげるステップを踏まないといけないんですね。

ブログを始めたばかりの時は特に問題は感じませんでしたが、記事が増えていく内に、「アレ、2ページ目読み込めないジャン・・・」という問題が発生。2ページ目以降が404エラーを返します。

半日近く試行錯誤した上で、この方法にたどり着きました。これは、カスタム投稿が含まれた時だけの問題ではなくて、通常のnext_posts_linkやWP-PageNaviのプラグインがエラー出てる!404!などといった時も有効かと思われますので、紹介させていただきます。

query_postsではなくis_main_queryを利用して解決

まずは結論から。この後に、問題発生から解決までの流れを書いていきますが、まずは解決方法です。

カスタム投稿タイプ「foo」を利用しており、ホームページに通常のポストと共にfooのポストを10件ずつ表示したい場合

以下をfunction.phpに記入します。


add_action( 'pre_get_posts', 'home_posts_type' );
function home_posts_type( $wp_query ) {
 if ( ! is_admin() && $wp_query->is_main_query() && $wp_query->is_home() ) { //管理画面以外 かつ メインクエリー かつ ホーム
 $wp_query->set( 'post_type', array( 'post', 'foo' ) );
 $wp_query->set( 'posts_per_page', 10 ); // 10件ずつ表示
 }
}

通常(というか私は今まで)、ループさせるテンプレート(index.phpとか)内でquery_postsを利用して、表示させるポストタイプとか、記事数を操作していたのですが、

これをfunction内で簡単に操作できる、is_main_queryを利用することによって解決しました。

function内で表示条件を変更出来るのでとっても簡単。is_main_queryを利用すれば、query_postsでわざわざ再定義する必要もありませんから、コードも綺麗になるし、なにより「なかなかうまくいかないなぁ」となることが少なくなるかと思います。

なぜこうなったのか。これまでの経緯

そもそもなぜこうなったのか、個人的なメモ。

今まではquery_postsを使ってテンプレート内から投稿の条件変更を行なっていました。それが以下のコードです。


<?php $paged = get_query_var('paged'); ?>
 <?php
 $args = array(
 'post_type' => array('post','foo'),
 'posts_per_page' => 10,
 'paged' => $paged
 );
 ?>
 <?php if(have_posts()):   query_posts($args);?>
 <?php while(have_posts()): the_post(); ?>

// loop内容

<?php endwhile; ?>

// ページ送りリンク

<?php wp_reset_query(); ?>
<?php endif; ?>

これだと、2つの投稿タイプが表示されるし、1ページの投稿数も操作されるけど、2ページ目がなくなってしまいました。なぜだろう。

他にも条件を適用させるために$query_string .や、&paged=’.$pagedも試したけど、効果なし。

また、「query_posts内で、’posts_per_page’ => 10を設定し、WordPressの管理画面の表示設定で「1ページに表示する最大投稿数」を1件にする」といった方法も多くの記事で紹介されていましたが、なぜか表示されるはずの3ページ以降が404エラー。なんでや。

通常のポストでページ数を判断するWordPress

なぜだー!と、思ってたら、ホームでは通常のポスト数でページ数を判断していることが色々やっている内に判明(ここまでが長かった(TдT))。

つまり、カスタム投稿がいくら多くても、2ページ目は識別されないということ。更にこの「表示設定で「1ページに表示する最大投稿数」を1件にする」という方法は、通常ポストが2件あったら、2ページ目までは有効になる。という方法です。

つまりここでは以下のような問題が発生します。

仮にホームで1ページに表示する記事数を10件にしたくて、postの投稿数は2、fooの投稿数は20で、2つの投稿タイプの投稿数の合計が22あった場合を想定しましょう。

ここでの期待する動きは「3ページ目(http://example.com/page/3/)までページングが成功して、4ページ目から404、ページが見つかりません」という状況になることです。

実際どうなるかというと、

1ページの表示を1件に管理画面に設定して、query_postsで10件表示するように設定した場合、3ページ目が表示されません。3ページ目が404エラーを返します。

逆に、postの投稿数が20、fooの投稿数は2の場合、通常ならば4ページ目が404エラーを返すはずが、21ページ目でやっと404エラーを返すことになります。

この問題に関しては、フォーラムでjim912さんが説明して下さっていました。

WordPressのデフォルトでは、通常投稿(post)のアーカイブ表示となります。
この場合、query_postsを行う前は、このデフォルトのロジックで動作するため、投稿の公開記事の全数が2ページ目を表示するほどないと、404になってしまいます。

なるほど。そんな仕様になっていたのかと目からウロコでした。

で、この問題を解決するために固定ページをフロントページにしたり、is_main_queryを使用する方法があるのですが、今回は簡単だったis_main_queryを利用して解決しました。

最後に

末尾にですが、解決に至るまで沢山の記事を参考にさせて頂きました!参考URLを載せていますので困っていたらぜひご覧頂くことをおすすめします。

解決の糸口!公式フォーラム:http://ja.forums.wordpress.org/topic/11147

3.3の新しい関数 is_main_query を使おう

WordPressでホームやアーカイブ毎に表示条件を変える(is_main_query と pre_get_posts フック)

※query_postsでも問題解決出来ることがありますので、その際参考にさせて頂いた素晴らしい記事の方々!

諦めないで…!WordPressでページ送りがうまく行かない時の3つの対処法+究極奥義

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

WordPressの問題は、大抵解決方法がどこかに掲載されていたりします。ぜひ、諦めないでWordPressを利用していきましょう!

  • このエントリーをはてなブックマークに追加

関連記事

Webデザインレビューやってます

コメントをどうぞ。

  • Hiroaki Endo

    2日ほどごちゃごちゃやっていましたが、この記事に救われました。
    ありがとうございました!!
    自分の場合は、postは使わずに5種類のカスタム投稿を使おうとしてTOPに固定ページを作ったのですが、うまくいかず、記事中の参考urlの対策方法もうまくいかずあきらめかけていました。
    本当に助かりました。
    ありがとうございます。

  • aki

    まさにこれがやりたかったんです・・・!
    とても助かりました!

    なんでカスタム投稿使うと一気にめんどくさいんですかね・・・

    他のフィルターをフックしようとして1日使ってしまいました・・・

    ありがとうございました!

1日1Webデザイン

あなたにとっての素晴らしいWebデザインが見つかりますように。

Webデザインレビュータグクラウド

ホバーしてね