前回の記事で書いた以下の記事で、残課題としてページネーションがうまくいかないという話を書きました。
WORDPRESSでページネーションがうまくいかないという検索をするとたくさんページが出てきましたが、私の場合、そのどれにも当てはまらなかったので、私の解決策が適用できる方もいるのではないかと思い、記事にします。
日本語タイトルで記事を書いていると、英語のように単純にタイトルを利用して記事をタイトル順に並べることが出来ないため、フリガナにあたるカスタムフィールドを記事に付与して、その順に並べる事ができます。しかし、記事数が膨大だとそれだけでは、検索性向上には役立たない為、タイトルの頭文字「あ」とか「い」で始まる記事毎にページを作りその中で、フリガナ順に並べ替える方法を記事にしました。前回は、記事を50音順に並べるためカスタムフィールドを利用しました。前回の記事は、以下の通り この方法は、カテゴリを絞り込ん... [WORDPRESS]タイトルの頭文字別に50音順に並べる - 演劇とかの感想文ブログ |
私のページネーションがうまく行かなかった時の状況
先程の記事に書いたように、メタデータを複数使った検索、並べ替えをおこなった場合だけ、ページネーションがうまく働きませんでした。
状況を整理すると以下のような状況です。
ページネーションで通常通り次のページに行ける場合
・普通の記事一覧(カテゴリ別や、タグ別の一覧)
・プラグイン List Category Postを使った場合
ページネーションが上手く行かない場合
・前回紹介した自作ショートコードで、複数ページに渡った場合。
上記の画面イメージのようにページネーションは、うまく表示されるのですが、「2」をクリックしても同じ画面が表示されるだけでした。
どう考えても、自分のショートコード内の何かコードが悪いのだとおもっていましたが、別の解決策で解決しました。
自動的にリダイレクトする仕組みが問題でした。
結論としては、先日作成したショートコードのfunctionとは別に、以下の関数を作成したらうまくいくようになりました。
/** * 存在しないURLからの自動リダイレクトを無効化します。 */ function remove_redirect_guess_404_permalink( $redirect_url ) { if ( is_single() ){ $subject = $redirect_url; $pattern = '/\/page\//'; // URLに「/page/」があるかチェック preg_match($pattern, $subject, $matches); if ($matches){ //リクエストURLに「/page/」があれば、リダイレクトしない。 $redirect_url = false; return $redirect_url; } } } add_filter( 'redirect_canonical', 'remove_redirect_guess_404_permalink' );
この関数は、reidrect_canonical関数が動く際に、文字列内に/page/が含まれている場合は、リダイレクトをしないというふうにするための関数です。
何が問題だったのか?
WORDPRESSは、間違ったURLがリクエストされた場合、近いURL候補にリダイレクトする機能があります。それを担っているのが、redirect_canonicalという関数です。
この関数が、ページネーションが返してくる「(元のURL)/page/2」みたいなURLを(おせっかいにも!)「(元のURL)」に戻してしまうのです。
これに気づいたのは、前回のコードの中の以下の文の挙動に不信をいだいたからでした。
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
この関数の戻り値である$pagedの値をecho文を使って、ページ上に表示させるようにすると、2ページめ以降をクリックしても、常に1が返ってくることがわかりました。
この関数の挙動を色々調べると、URLの「/page/2」となっている「2」の部分を取得する関数のようです。そういえば、何度ページネーションの「2」をクリックしても、URLは同じままです。
例えば、カテゴリの公演(show)の一覧を表示するURLは以下のような感じです。
そして、ページネーションの「2」をクリックするとこうなります。
ところが、自分の作ったショートコードで出来たページネーションをクリックしても、上記のように後ろに/page/2といった要素が追加されません。
クリックする前に、マウスポインタを「2」に合わせると、リンク先は確かに/page/2がついています。
それなのに、クリックした先は、「/page/2」が付かないURLにしかなりません。
色々、調べた挙句、redirect_canonicalの機能で、リダイレクトされていることに気づきました。
以下のブログ記事のコードをコピペすることで、解決しました。
ちなみに、以下の記事も参考にしました(今回の僕のパターンには合いませんでしたが、固定ページで一覧をカスタマイズでつくるべきではないという話はわかりました。)
「WordPressでページ送りが動かないのはどう考えてもquery_postsが悪い!【pre_get_posts、WordPressループまとめ】」