Author.phpには2つのループがあります。その作者からのすべての投稿を取得するデフォルトのメインループと、$secondloop
という別のカスタムWP_Queryです。両方のクエリともposts_per_page
が 3 に設定されています。 両方のクエリ結果をページ分割したい .
このために$secondloop = new WP_Query($args)
に引数を追加しました:
"paged" => (get_query_var('paged')) ? get_query_var('paged') : 1;
(読む:このクエリのページをメインクエリのと同じページに設定してください)。
メインループが私に5つの投稿を与え、私の$secondloop
が私に2を与える場合、 page 2 を呼び出しても問題ありません。それは私にメインループからの残りの2つの投稿と私の$secondloop
からの投稿を表示しません(それはwhile ($secondloop->have_posts())
の中に入らないので)。
_ but _ メインループの投稿数が2で$secondloop
の投稿数が5の場合、 page 2 を呼び出すと 404 :(となります。代わりに$secondloop
の残り2件の投稿が必要です。
メインループからのmax_num_pages
を超えたことをWordPressが検出すると、そこにあるPHPコードは実行されなくなるため、author.phpテンプレート内の何かを変更しても意味がありません。 。
その振る舞いをどうやって "上書き"できますか?
author.php (ちょうど役に立つビット)
<?php if (have_posts()) { ?>
<div class="row archive-grid">
<?php while (have_posts()) : the_post();
include(locate_template('parts/loop-archive-grid.php'));
endwhile; ?>
</div>
<?php }
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$secondloop = new WP_Query(array(
"post_type" => "musikalbum",
"posts_per_page" => 3,
"author_name" => get_query_var('author_name'),
"paged" => $paged
));
if ($secondloop->have_posts()) { ?>
<div class="row archive-grid">
<?php while ($secondloop->have_posts()) : $secondloop->the_post();
get_template_part( 'parts/loop', 'album-grid' );
endwhile; ?>
</div>
<?php author_page_navi( $loop );
} else {
joints_page_navi();
} ?>
My functions.php でmy メインクエリのposts_per_page
を設定する
function my_post_queries( $query ) {
if (!is_admin() && $query->is_main_query()){
if (is_author()){
$query->set('posts_per_page', 3);
} else {
$query->set('posts_per_page', 9);
}
}
}
add_action( 'pre_get_posts', 'my_post_queries' );
ミロは私の functions.php にこれを追加することを提案した答えを私に指摘した。
function my_404_override() {
global $wp_query;
if (is_author()) {
status_header( 200 );
$wp_query->is_404 = false;
}
}
add_filter('template_redirect', 'my_404_override');
しかし、それでも404エラーが表示されます。 if節を削除するとindex.phpが表示されますが、これは意図したものではありません。だから私はそのif句が必要です...しかし、WordPressはまだそれを知っていないようです!
コードをテンプレートに直接貼り付けても、get_header();
の前の3行であってもうまくいきませんでした。
global $wp_query;
status_header( 200 );
$wp_query->is_404 = false;
私はtemplate_redirect
にフックするためにpre_get_posts
を捨てました:
function my_post_queries( $query ) {
if (!is_admin() && $query->is_main_query()){
if (is_author()){
$query->set('posts_per_page', 3);
// NEW CODE:
$paged = (get_query_var('paged')) ? intval(get_query_var('paged')) : 1;
global $original_page_request; // saves the original value of $paged because I'm about to alter it!
if ($paged > $query->max_num_pages) {
$query->set('paged', $query->max_num_pages);
$original_page_request = $paged;
} else {
$query->set('posts_per_page', 9);
}
}
}
add_action( 'pre_get_posts', 'my_post_queries' );
そのアイデアは、メインクエリのpaged
がmax_num_pages
を超えたときに手動でリセットし、私のglobal $original_page_request
の "実際のページ"を$secondloop
に格納してpaged
パラメータをに設定することでした。 残念ながら、うまくいきません。 404が表示されなくなったことをとてもうれしく思いましたが、今度はメインクエリページを自動的に0に設定します。Why 0 ?!
pre_get_posts
では、WordPressが投稿する前にコードが実行されるためです。 $query
へのアクセスはありますが、それはクエリ変数を設定するためだけのもので、検索される投稿がないため、計算するmax_num_pages
はありません。
つまり、max_num_pagesを超えようとしているときにはわからないということです。
それから新しいコードをmy_post_queries( $query )
からwp
にフックする別の関数にコピーしました。そこでは、max_num_pages
は有効な番号であり、is_author()も正しいです。投稿数を超えても、まだ運がありません。 404.私は$wp_query->is_404 = false
を設定することができました、しかしそれは再びインデックスに私を返します。
ページが読み込まれるたびに、WordPressはこれらの機能をそれぞれの順序で実行します。
init();
parse_request($query_args);
send_headers();
query_posts();
handle_404();
register_globals();
メインクエリがquery_posts()
の後で終了するところ。 この時点では、WordPressはテンプレートとすべてのクエリ変数を知っています max_num_pages
のように。
handle_404()
では、 メインクエリ に投稿がある場合、関数は戻り、WordPressはテンプレートの読み込みを続けます。それ以外の場合は404 HTTPステータスを送信し、代わりに404テンプレートをロードします。
WordPress 4.5以降、pre_handle_404
と呼ばれるフィルタフックがあります。これがtrue
に設定されている場合、handle_404()
は( メインクエリ に投稿があるかどうかにかかわらず)を返し、テンプレートは引き続きロードされます。
そのため、 lot をいじると、これはついにうまくいきます。これをあなたの functions.php に追加してください:
function ignore_404_past_max_page($bool = false, $query) {
$paged = (get_query_var('paged')) ? intval(get_query_var('paged')) : 1;
if (is_author() && ($paged > $query->max_num_pages))
$bool = true;
return $bool;
}
add_filter( 'pre_handle_404', 'ignore_404_past_max_page', 10, 2);
それでおしまい!既存の関数を編集する必要はありません。クリーンにして、実行したいとおりの処理を実行します。WPを404ingから除外します。 WordPressをバージョン4.5に更新してください (以上)!
不要な副作用として、PHP_INT_MAX
までページングして空のページが表示されることがあります(get_the_author_meta()
やget_wp_user_avatar()
を追加しない限り)。おそらく、データベース内の各作者の最大ページ数を記憶し、それをクエリして$paged
と比較して、上記の関数で$bool
をfalse
に設定できます。しかし、私は 本当に それが現在どのように機能するかに満足しています。