web-dev-qa-db-ja.com

ページ付けは20ページ後に404を返す

私はカスタム投稿タイプから1ページあたり4の投稿を引き込むページループを持っています。ページネーションがそれ以降のすべてのpage/20を通過しないという欠点があり、posts_nav_linkには次の矢印がまったく表示されないという唯一の欠点があります。ページのようにちょうどそこにはありません。

カスタム投稿タイプには、合計119の公開された投稿があります。 posts_per_pageを6に変更すると、最後からもっと多くの投稿にアクセスできるようになりますが、page/20でも停止します。

本番サイトでは、ページ付けは21で停止します。ライブデータベースにはより多くのエントリがあるためと思います。

[ブログページの最大表示数]設定を6に設定しました。

これが私が使っているループです:

<?php
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args  = array(
    'posts_per_page' => 4,
    'orderby'        => 'modified',
    'post_type'      => "projekte",
    'paged'          => $paged
);
$custom_query = new WP_Query($args);
$c = 0;
while($custom_query->have_posts()) :
    $custom_query->the_post();
    ?>
    <article>...</article>
    <?php
endwhile;
wp_reset_postdata(); // reset the query
?>

私はfunctions.phpを何百回も調べて、制限のあるget_pre_postsフィルタを探しましたが、私が見ることができるものは何もありません。

私はまたエラーログセットアップを得ました、そして何もそこに返されません、私はそれがうまくいくことをテストしました。

助言がありますか?

4
any_h

あなたが経験していることはかなり普通で予想されています。これは私がこの点でいつも悩んでいる大きな理由の1つです、ホームページまたはどんなタイプのアーカイブページでもメインのクエリをカスタムのクエリで置き換えないでください。彼らは一つの問題を解決しますが、たくさんの他の新しい問題を生み出します

あなたが持っているものとあなたがこれらの結果を得ている理由を見てみましょう:

基本

アーカイブページに出力は表示されませんが、メインクエリは every page loadで実行され、関係なく投稿の配列を返します。ループを削除しても、メインクエリの実行は停止されません。ループは、メインクエリによって取得されているものを表示するだけです。つまり、基本的に何が起きているのでしょうか。デフォルトのループをカスタムのものに置き換えると、ページロードごとに2セットの投稿が取得されます。メインクエリによって取得された投稿とカスタムクエリによって取得された投稿。これをテストしたい場合は、phpタグ内のアーカイブページのループの外側に次のコード行を追加してください。

?><pre><?php var_dump( $wp_query->posts ); ?></pre><?php

これは、その特定のページのメインクエリによって取得された投稿の配列を出力します。

これがカスタムクエリをメインクエリに置き換えたときに非常に効果がなくなります。それは先端が上の形になっている空気入りタイヤをパンクした、磨耗したタイヤと交換するようなものです。

あなたのシナリオ

次のようなシナリオがあります

  • カスタム投稿タイプからの119投稿

  • Adminで設定されたページごとの投稿数オプションは6です

  • カスタムクエリは、1ページに4件の投稿を取得するように設定されています

数学

あなたのメインクエリはあなたがecho $wp_query->max_num_pages;でテストできる20ページを返します。数学は簡単です、あなたはまたあなたがecho $wp_query->found_posts;でチェックすることができます119のポストを持っています、ページあたりのポストはadminで6に設定されているので、119/6 = 20の天井

カスタムクエリについては、$wp_query$custom_queryに変更することで上記と同じ情報にアクセスできます。あなたはまだ119の投稿があることがわかりますが、1ページあたりの投稿数は4に設定されているため、30ページになります。119/ 4 = 30の上限

ページ21の404

メインのクエリで表示する投稿がないときはいつでも404がトリガーされます。これはあなたが見ているものです。 21ページ以上ではなく20ページを埋めるのに十分な投稿があります。そのため、21ページに移動すると、メインクエリ404が表示されるのは、カスタムクエリから表示できるものがまだたくさんあるかどうかに関係なく、表示される投稿がこれ以上ないためです。

解決策は簡単だと言う投稿を見たことがありますが、管理ページの1ページあたりの投稿数をカスタムクエリの投稿数に合わせて変更するだけです。 絶対にしないでください 。はい、それは問題を解決します、しかしそれはあなたがメインのクエリをカスタムのもので置き換えるべきでないというここでの本当の問題を打ち負かします。ところで、問題の本当の解決策は非常に単純、きれい、そしてあなたが必要とするものを達成するための適切な正しい方法です。

カスタムクエリの理由

2つの理由から、カスタムクエリを使用することにしました

  • カスタム投稿タイプのアーカイブページの1ページあたりの投稿数が他のサイトと異なる

  • デフォルトの投稿日ではなく、修正した日付で投稿をソートする

見ての通り、あなたはあなたのカスタムクエリに関する2つの問題を解決しましたが、他の問題を作成しました

ソリューション

これはあなたの問題を解決するための正しい、簡単な方法です。実行前にメインクエリを変更するには、pre_get_postsを使用します。 pre_get_postsはそれに応じてクエリ変数を変更し、特定のページリクエストに対するSQLクエリを計算するために使用されます。

ここで2つのことをする必要があります。1つ目はアーカイブページのカスタムクエリを削除してデフォルトのループに置き換えることです。それが完了したら、それはデフォルトであるはずなのであなたは投稿日順に並べられたページあたり6の投稿を見るでしょう。

では、functions.phpを開いてpre_get_postsを使って1ページあたりの投稿数とソート順を修正しましょう。

add_action( 'pre_get_posts', function ( $q ) 
{
    if(    !is_admin() 
        && $q->is_main_query() 
        && $q->is_post_type_archive( 'projekte' ) 
    ) {
        $q->set( 'posts_per_page', 4          );
        $q->set( 'orderby',        'modified' );
    }
});

カスタム投稿タイプのアーカイブページに正しくページングされた、修正された日付順に並べられた1ページあたり4件の投稿が表示されます。projekte

余分な読書

また、私がしばらく前に同様の問題について行った次の投稿と、その特定の投稿でリンクしたすべての投稿を読む必要があります。

編集

クロージャーをサポートしていない恐竜のphpバージョンで立ち往生している人のために、ここにpre_get_postsアクションのフォールバックバージョンがあります。

add_action( 'pre_get_posts', 'wpse176347_pre_get_posts' );
function wpse176347_pre_get_posts( $q ) 
{
    if(    !is_admin() 
        && $q->is_main_query() 
        && $q->is_post_type_archive( 'projekte' ) 
    ) {
        $q->set( 'posts_per_page', 4          );
        $q->set( 'orderby',        'modified' );
    }
}
18
Pieter Goosen