あんまりやりたくないパターンだけど、WordPressの固定ページテンプレート内で記事一覧を表示させ、あまつさえページネーションもつけたいというときがある。
このページネーションの2ページ目以降が404になってはまったけど、動かない原因と対策がわかったのでメモ。
なぜ404となるのか
固定ページ内でページネーションを使うと404になる原因についてですが、たぶん以下のような感じだと思います。
- ページネーションの仕様上、2ページ目とかのURLに、/page/2/とかがつく
- 例えば/hoge/page/2/のようなパーマリンクになる
- そんな固定ページはないので、404になる。
まぁ、固定ページでそもそもページネーションできるようになっていないんでしょうね。そりゃそうよ。
解決策
/page/2/みたいにならなければいいんじゃないか。
WordPressでは、上記のようなURL構造でなくとも、?page=2みたいなパラメータでもページネーションになります。
ただし、デフォルトだと?page=2にアクセスしても、/page/2/にリダイレクトされてしまう。
よって、ページネーションのURLの形式を?page=2にして、なおかつ勝手にリダイレクトさせないようにすればOK。
実装
functions.phpに以下を記述
add_filter('redirect_canonical','my_disable_redirect_canonical');
function my_disable_redirect_canonical( $redirect_url ) {
if ( is_archive() ){
$subject = $redirect_url;
$pattern = '/\/page\//'; // URLに「/page/」があるかチェック
preg_match($pattern, $subject, $matches);
if ($matches){
//リクエストURLに「/page/」があれば、リダイレクトしない。
$redirect_url = false;
return $redirect_url;
}
}
}
続いて、ページネーションのほうは以下のようにする。
<?php
$paged = (int) get_query_var('paged'); // $pagedを定義。これがないとページネーションが動かないっぽい
$wp_query = new WP_Query();
$param = array(
'post_type' => 'hoge',
'paged' => $paged
);
$wp_query->query($param);
if($wp_query->have_posts()):
while($wp_query->have_posts()) : $wp_query->the_post();
?>
ここで記事をループさせる
<?php endwhile; endif; ?>
<?php
if ($wp_query->max_num_pages > 1): // ここからページネーション
echo '<div class="new-pagenation">';
echo paginate_links(array(
'base' => get_pagenum_link(1) . '%_%',
'format' => '?paged=%#%',
'current' => max(1, $paged),
'total' => $wp_query->max_num_pages,
'next_text' => '次へ',
'prev_text' => '前へ'
));
echo '</div>';
endif;
?>
paginate_links()というナイスな関数を使うのが肝で、パラメータでURLのフォーマットを設定することができる。他にもいろいろパラメータを設定できる優れもので、僕もこんな関数があることを初めて知りました。具体的な使用方法はWordPress Codexを参照してください。
次回以降普通のページネーションでもこれ使おう…
あとは、paginate_links()で出力されるhtmlに合わせ、スタイリングしてやりましょう。
以上、現場からでした。
これでも動かない場合は、こっちも見てみてね。

コメントを残す