WPには「redirect_canonical」という filter hook があり、よしなにリダイレクトして URL を正規化している。
カスタムポストタイプの一覧ページは
- https://example.com/custom/ (1ページ目)
- https://example.com/custom/page/2/ (2ページ目)
- https://example.com/custom/page/3/ (3ページ目)
- https://example.com/custom/page/4/ (4ページ目)
とページネーションされており、「redirect_canonical」によって
「https://example.com/custom/page/1/」は「https://example.com/custom/」にリダイレクトされる。
今回は、「https://example.com/custom/」と「https://example.com/custom/page/1/」ページを混在させる方法を紹介する。
まず、「redirect_canonical」によるリダイレクトを解除する。
add_filter( 'redirect_canonical', function( $redirect_url ) {
global $paged;
if ( is_paged() || ( isset( $paged ) && $paged === 1 ) ) {
return false;
}
return $redirect_url;
} );
その後、「template_redirect」の action hook などでテンプレートを分岐する。
global $paged;
if ( !is_paged() || ( isset( $paged ) && $paged === 1 ) ) {
// https://example.com/custom/page/1/ など paged クエリバーに値がある場合
} else {
// https://example.com/custom/
}
そして、最後にページネーションのリンクで「https://example.com/custom/」と書かれているものを「https://example.com/custom/page/1/」に書き直すだけだ。
// https://developer.wordpress.org/reference/functions/get_pagenum_link/
// のソースコードそのまま。長いコードがいやなら正規表現などで書き換える
add_filter( 'get_pagenum_link', function( $result, $pagenum ) {
global $wp_rewrite;
$pagenum = (int) $pagenum;
$request = remove_query_arg( 'paged' );
$home_root = parse_url( home_url() );
$home_root = ( isset( $home_root['path'] ) ) ? $home_root['path'] : '';
$home_root = preg_quote( $home_root, '|' );
$request = preg_replace( '|^' . $home_root . '|i', '', $request );
$request = preg_replace( '|^/+|', '', $request );
if ( ! $wp_rewrite->using_permalinks() || is_admin() ) {
$base = trailingslashit( get_bloginfo( 'url' ) );
// if ( $pagenum > 1 ) {
$result = add_query_arg( 'paged', $pagenum, $base . $request );
// } else {
// $result = $base . $request;
// }
} else {
$qs_regex = '|\?.*?$|';
preg_match( $qs_regex, $request, $qs_match );
if ( ! empty( $qs_match[0] ) ) {
$query_string = $qs_match[0];
$request = preg_replace( $qs_regex, '', $request );
} else {
$query_string = '';
}
$request = preg_replace( "|$wp_rewrite->pagination_base/\d+/?$|", '', $request );
$request = preg_replace( '|^' . preg_quote( $wp_rewrite->index, '|' ) . '|i', '', $request );
$request = ltrim( $request, '/' );
$base = trailingslashit( get_bloginfo( 'url' ) );
if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' !== $request ) ) {
$base .= $wp_rewrite->index . '/';
}
// if ( $pagenum > 1 ) {
$request = ( ( ! empty( $request ) ) ? trailingslashit( $request ) : $request ) . user_trailingslashit( $wp_rewrite->pagination_base . '/' . $pagenum, 'paged' );
// }
$result = $base . $request . $query_string;
}
return $result;
}, 10, 2);
以上、複雑になるだけで使い所はほとんどなく、このあとにいろいろ問題が出てくると予測されるが、一度現場で必要だったので、備忘録としてここに残しておく。