なんか変なタイトルになったけれど、やりたいことは、WordPressのナビゲーションバーから「ランダム」みたいな項目を作って、それをクリックするとランダムな投稿記事に遷移させたい、ということです。
方法として、開いた瞬間にランダムなページにリダイレクトする固定ページを作って、その固定ページをナビゲーションメニューに表示させる感じ。ちなみにこのサイトでは実装していない(そんな需要ないと思うし)。
環境
- WordPress 5.2.3
- nginx 1.12.2
- php 7.1.4
やりたいこと
WordPressのナビゲーションメニューに「ランダム」みたいなメニュー項目を作って、そいつをクリックしたら何かのランダムな投稿記事に飛ばしたい。
やり方
いろいろなやり方があると思うのだけれど、多分楽なのは強制的にリダイレクトする固定ページを作って、それをメニューに表示させることかな、と思う。ので、その方向で実装を考える。
リダイレクトにはhtmlやJavaScriptを使ったクライアント側の方法と、phpを使うやり方、あるいはWordPressで用意された関数を使うサーバーサイド側やり方がある。DBにアクセスして、その情報を使うことを考えると、サーバーサイド側で対応したほうが楽だろう。で、WordPressに用意された関数があるのであれば、生のphpを使ってリダイレクトするよりもよいと思われる。わざわざそれ用の関数を作っているということは、裏でいろいろな処理が必要かもしれないので。
で、調べてみるとwp_redirect()なる関数があるので、まぁこれを使うのがよいだろうな、と。関数リファレンス/wp redirect - WordPress Codex 日本語版によれば、リダイレクト先の絶対パスがわかればよいらしい。
ということで、次の問題はランダムな記事のURLをいかにして引っ張ってくるか、である。ランダムな記事、みたいなワードで調べると、やたらWP_Query()を使った記事が出るのだが、コードを見るとどうも嫌な感じがする。影響大きくない?リファレンス(関数リファレンス/WP Query - WordPress Codex 日本語版)を見ても
ほとんどの場合、クラスの内部やグローバル変数を使わなくても欲しい情報は手に入れられるでしょう。どこからでも欲しい情報を手に入れるために、とてもたくさんの関数があるのですから。
関数リファレンス/WP Query - WordPress Codex 日本語版
とあり、どうも基本的には推奨されない関数に思える。少なくとも、適当な記事のURLがほしいだけの目的にはそぐわなさそうだ。
色々調べた結果、get_posts()でランダムな1記事をゲットして、その情報を取得するのが簡便に思えた。まぁ正直もっとよい解法があるような気もする。get_post()でランダム指定できれば楽だがそういうわけにもいかないようだ。
とにかく、これでリダイレクトはできるとして、どのファイルにコードを記述したらよいか、だが、固定ページなのでpage.phpに記述すればよい。その中で、is_page(slug)で条件分岐してやれば、任意のslugの固定ページでのみリダイレクトさせることができる。注意点として、page.phpの最初に記述してやることだ。でないと、表示がうまくいかない。内部の動きはよくわからないが、wp_redirect()は単にページ遷移しているだけではないらしい。
ソースコード
これまでのことをまとめて、コードを書いていく。
まず空の固定ページを作る。ここで、固定ページのスラッグを'random'とするが、別になんでもよい。is_page()で指定できればなんでもよい。で、作ったらpage.phpの頭に以下のようなコードを書く。
<?php
if (is_page('random')) {
$args = array(
'posts_per_page' => 1,
'orderby' => 'rand',
'post_type' => 'post',
'post_status' => 'publish',
'suppress_filters' => true
);
$rand_post = get_posts($args)[0];
$location = get_permalink($rand_post);
wp_redirect($location);
exit;
}
?>
短いコードで、難しいこともしていないので、特に解説の必要はないと思うが、軽くメモ書きしておく。
if (is_page('random')) {...} により、スラッグが'random'の固定ページでのみの処理としている。
get_posts()のパラメータを$argsで指定している。orderbyを'rand'にするのが唯一と言っていいポイントだ。ここでカテゴリーなどを指定することで、特定の範囲に絞ったランダム記事に飛ばすこともできる。
で、1記事で十分なので、$rand_postにリストの1番目を入れて、その記事のパーマリンクの文字列をget_permalink()で取得する。ループ内で使うthe_permalink()じゃないよ。
で、取得したリンクにwp_redirect()で飛ばす。第二引数にステータスコードを入れることもできるのだが、省略すると302になる。302は一時的な遷移の時に使われるもので、まぁ今回のケースに合致するかは微妙な気もするんだが、少なくともドメインの引っ越しとか恒久的なリダイレクトで使われる301よりは意味が近いだろうから、まぁそのままでよいかな、と。
おわり
以上で、ナビゲーションメニューにランダム遷移な項目を追加できた。まぁエンタメ系のサイトだと、こういうのも意味あるかな、と思って作ってみた。このサイトだとあんまり意味ないと思うので、このサイトには実装せず。
それにしても、WordPressでしかPHPを使わないので、時々手を入れようとするととても疲れる。セミコロンうち忘れて技術的な問題を発生させまくる私。Cだと忘れないのにPHPだと忘れるのは何故だろう。
コメント