Wordpressのトップページの記事一覧表示をランダム順に変更する方法です。
デフォルト設定ではトップページの記事一覧は新着順に表示されますが、これを日付や時間に関係なくランダムに表示したい時があります。
管理画面から変更することは出来ませんが、functions.phpにコードを追記することでランダム順に変更することが出来ます。
1ページ目と2ページ目の記事が重複する問題についても解説します。
この記事の目次
functions.phpで記事をランダム順に変更する
Wordpressではトップページなどの記事一覧は新着順(公開日順)で表示されます。
一般的なブログならこの表示順でも良いのですが、まとめサイトのように同じようなジャンルの記事ばかりを取り扱うサイトではランダム順の方が良いことがあります。
例えば、特定ジャンルの画像ばかりを載せたサイトでは"公開日"はあまり重要ではなく、過去の記事もトップページにピックアップしていった方が良いことでしょう。
Youtubeのトップページをイメージしていただくと良いかもしれません…
色んな記事を回覧してもらえるなら、新着順よりもランダム表示の方が効果的です。
ということでトップページの記事の表示をランダム順に変更する方法です。
ただWordpressにはそのような機能は付いていないのでfunctions.phpを使って表示順をランダムに変更します。
予めお伝えしておくと、記事のランダム表示は何かの順番で表示する方法とは違い、1ページ目に出た記事が2ページ目にも出てしまうという特徴があります。
何かの順番ならこのようなことは起きないのですが、ランダムなのでこうなります。
この問題に対処する方法も書きました。では順番に見ていきましょう!
pre_get_postsでランダム表示
前置きが長くなりましたが、実際に使用するコードです。
まずは記事の並び替えに定番のpre_get_posts
フックを使った方法です。
以下のコードを子テーマのfunctions.phpに追記すればOKです。
//記事ランダム表示 function sortpost_rand($query) { if(is_admin() || !$query->is_main_query()){ return; } $query->set('orderby', 'rand'); } add_action('pre_get_posts', 'sortpost_rand');
orderbyにrandを指定してメインクエリをカスタマイズしています。
これで記事一覧がランダム表示に変わります。
しかし、この方法ではページ遷移後に再度ランダム抽選が行われるため、2ページ目以降に1ページ目と同じ記事が出現してしまう可能性があります。
ということで続いてposts_orderby
フックを使う方法です。
ページネーションに対応したランダム表示
先ほどのコードで1ページ目と2ページ目に同記事が出てしまう原因は、2ページ目でも同じようにランダム抽選してしまうことにありました。なので"ある時点"でのランダム表示順を決定しておくことで、ページ遷移後も記事が被って表示されることは無くなるはずです。
う~んと思って調べたところ、既にこの問題に対応されている方がおられましたので、そちらのコードを参考にさせていただきました。
で、完成したコードがこちらです。
以下のコードをfuncitons.phpに追記すればOK!
コード中のコメントアウト(//部分)は適宜削除して使って下さい・w・
//記事ランダム表示 function sortpost_rand($orderby, $query){ if ( !is_admin() && $query->is_main_query() ) { if ( $query->is_home() ) { //$now = new DateTime(); $now = new DateTime('now', new DateTimeZone('Asia/Tokyo')); $seed = strtotime( $now->format('Y-m-d H:00:00') ); // $seed = strtotime( date('Y-m-d H:00:00') ); mt_srand($seed); $orderby = 'RAND(' . mt_rand() . ')'; } } remove_filter( current_filter(), __FUNCTION__ ); return $orderby; } add_filter( 'posts_orderby', 'sortpost_rand', 10, 2 );
posts_orderby
フックを使った方法です。ポイントは何といっても$seedで、ここに現在時間を入れることでページネーションに上手く対応できています。
コードはホーム(トップ)ページに対応するものですが$query->is_home()
の部分を適宜変更することで、ランダム表示するページの種類(トップとカテゴリーなど)を分けることもできます。
あとdate関数は2038年問題があるらしいので、DateTimeクラスを使いました。
さらにnew DateTime()
だと世界標準時間になるので、DateTimeZoneを引数に指定して日本時間を使うように変更しています。
参考
2038年問題は簡単に言えば32bit仕様のdate関数の計算上限です。
ある時期(2038年)を過ぎた時点でbitがオーバーフローするので、date関数の使用が非推奨になっているようです。
ランダム表示を変更するタイミングについて
参考先サイト様の解説にもありますが、上記のコードは('Y-m-d H:00:00')
の部分で「分」と「秒」を0に固定することで、「時間」ごとにランダム表示の順番が変更されるようになっています。
これで1時間単位、1日24回ランダム表示の順番そのものが変更されます。
イメージとしては以下のような感じです。
9:00~9:59と9時代の表示では記事の順番は変わりません。
そして9:59から10:00になった瞬間に記事の順番が変わるといった感じです。
ポイント
サイトにキャッシュ機能を導入している場合は、キャッシュクリアしないと記事の表示順が更新されない可能性が高いです。キャッシュクリアして動作確認するようにしましょう!
表示順変更のタイミングを変更したい時
Y-m-dの部分を変更すれば日ごとに更新というように変更することも出来ます。
//data内が更新時間の設定 $seed = strtotime( $now->format('Y-m-d H:00:00') );
ここを変更することで任意の時間ごとにランダム表示を更新することができます。
なおHの部分が時間ですが、分や秒単位に変更してしまうと記事順の保存期間が短すぎて意味がなくなってしまいます。
(1分以内に2ページ目を開かないと記事が被る可能性が出てしまう等。)
上記は1時間ごとですが、これを1日ごとに更新したいなら、
//1日ごとにランダム表示を更新 $seed = strtotime( $now->format('Y-m-d') );
のように日までのフォーマットを使うように変更すればOKです。
最後に今回出現したフォーマット文字は以下のような感じになっています。
文字 | 取得する日付/時刻 |
Y | 年、4桁の数字(2023など) |
m | 月、0付きの2桁の数字(01~12) |
d | 日、0付きの2桁の数字(01~31) |
H | 時刻、24時間単位(00~23) |
i | 分、0付きの2桁の数字(00~59) |
s | 秒、0付きの2桁の数字(00~59) |
日付や時刻のフォーマット文字(アルファベット)はこれ以外にも複数の種類がありますが、記事のランダム表示&更新という内容では上の種類だけで、年単位~秒単位まで対応できるので他のフォーマットを調べて使う必要はないと思います。
まとめ
Wordpressの記事の表示順をfunctions.phpでランダムに変更する方法でした。
記事ごとの公開日(新しさ)がそれほど重要でないサイトであれば、トップページの一覧をランダム表示にしておくと色々な記事にアクセスが流れて良いかも。
pre_get_posts
を使った方法が簡単ですが、ページネーションを考えるとあまり良くないのかもしれません。
もっとも1000記事とかあるなら被る確率はかなり少ないですけどね・w・