follow us in feedly
PHP

投稿一覧をランダムに表示する

ワードプレスの標準ループでは通常、投稿は時系列に取り出され最新の投稿から順に並びます。しかし、時系列とは関係性の薄いコンテンツの場合、アクセスごとに表示順を変えて変化を出すことも時として有効です。標準ループに少しだけ手を加えることで可能ですのでその方法を見ていきましょう。

2019年3月5日

標準のループ表示を確認

まずは完成形の確認です。当サイトの記事一覧ページを例にしますと、リロードするたびに記事の表示順が変わっているかと思います。

ワードプレス 投稿のランダム表示

リロードするたびに記事の表示順が変わる。

ワードプレス 投稿のランダム表示

では標準のループ表示から確認していきましょう。ワードプレスの標準ループの書き方は以下のようになるかと思います。このなかでhave_posts()は取り出す投稿があるかないかをtrue、falseで返してくれる組み込み関数で、the_post()は取り出すべき次の投稿を現在の投稿にセットする組み込み関数だとコーデックスには書かれています。これによって、現在の投稿を対象にしたthe_title()やthe_content()が使用できるようになっているわけです。

while文は条件式が真である限りその後の処理を繰り返すというものです。ここでの条件式は($query->have_posts())の部分ですので、取り出すべき投稿がある限り処理を繰り返し、全部取り出したら処理を終了するということになります。
関数リファレンス/have posts – WordPress Codex 日本語版
関数リファレンス/the post – WordPress Codex 日本語版

<?php $query = new WP_Query; ?>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
・
・
<?php the_title(); ?>
<?php the_content(); ?>
・
・
<?php endwhile; endif; ?>

shuffleで表示順をランダムに変える

投稿オブジェクトを配列に格納

それでは標準のループ表示に少しだけ手を加えて表示順をランダムに変えてみます。下記のように標準のループ表示のなかでは投稿の内容を出力せず、投稿のオブジェクトを配列$arrayに格納していきます。get_post()は引数に取った投稿IDの投稿オブジェクトを返してくれる組み込み関数です。4行目のように取り出された投稿オブジェクトが次々に$arrayという配列に格納されていきます。処理が終了した時点で$arrayの中身は[投稿1のオブジェクト, 投稿2のオブジェクト, 投稿3のオブジェクト・・・]のようになっています。
関数リファレンス/get post – WordPress Codex 日本語版

<?php $array = []; ?>
<?php $query = new WP_Query; ?>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
<?php $array[] = get_post($post->ID); ?>
<?php endwhile; endif; ?>

配列をshuffleしてループ処理

下記では1行目で$arrayをシャッフルしています。これによって$arrayの中身がランダムに並べ替えられました。後はforeachで$postとして一つずつ取り出せば、後は標準のループと同じ処理が可能ですのでthe_title()やthe_content()も同じように使用することができます。これで表示順をランダムに変えることができました。もちろんこれは標準の投稿でもカスタム投稿でも同じことですし、出力する内容がカスタムフィールドでも変わりませんのでご参考ください。

<?php shuffle($array); ?>
<?php foreach ($array as $post) : ?>
・
・
<?php the_title(); ?>
<?php the_content(); ?>
・
・
<?php endforeach; ?>

ちなみに特定のカテゴリーに属する記事の直近何件か(1ページの表示件数の設定値)の中からランダムに5件を取り出して表示する場合は以下のようになります。ここでは2行目でIDが1のカテゴリーを指定しています。7行目ではシャッフルされた配列の先頭から5つを取り出しています。これでリロードするたびにランダムに5件が取り出され表示されます。

<?php $array = []; ?>
<?php $query = new WP_Query('cat=1'); ?>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
<?php $array[] = get_post($post->ID); ?>
<?php endwhile; endif; ?>
<?php shuffle($array); ?>
<?php $array = array_slice($array, 0, 5); ?>
<?php foreach ($array as $post) : ?>
・
・
<?php the_title(); ?>
<?php the_content(); ?>
・
・
<?php endforeach; ?>

アクションフックpre_get_postsを使用した方法も

実はランダム表示はアクションフックを使用しても可能です。pre_get_postsはクエリに変更を加え、変更されたクエリをWP_Queryに渡してくれます。従って、今回のようなランダム表示や、更新日時順、コメントが多い順なども簡単に実現することができます。ただし、この方法は管理画面などの投稿一覧もランダム表示になってしまいますので下記記述3行目のように、どのページでランダム表示するのかを限定するようにします。
プラグイン API/アクションフック一覧/pre get posts – WordPress Codex 日本語版

■functions.php
function sort_orderby_rand($query) {
  // 管理画面以外
  if (!is_admin()) {
    $query->set('orderby', 'rand');
  }
}
add_action('pre_get_posts', 'sort_orderby_modified');

また、下記のようにWP_Queryの引数にパラメーターを与えることでもランダム表示は可能です。

<?php $query = new WP_Query(array('orderby' => 'rand')); ?>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
	・
	・
	・

以上で「投稿一覧をランダムに表示する」の解説を終わります。

このエントリーをはてなブックマークに追加