【WordPress】一覧ページで記事をランダムに表示する

WordPress

WordPressの一覧ページで記事をランダムに表示する方法を紹介します。固定の表示順にしたくない場合や、関連コンテンツをランダムに見せたい場合に使えます。メインループ・WP_Query の2通りと、ランダム表示につきものの「2ページ目以降で重複する」問題への実用的な対処まで解説します。

この記事でわかること

  • pre_get_posts でアーカイブのメインループをランダム表示にする
  • WP_Query でランダムな記事一覧を取得する
  • カテゴリーを絞ってランダム表示する
  • ORDER BY RAND() のパフォーマンス注意とキャッシュ
  • 2ページ目以降の重複を防ぐ方法
スポンサーリンク

メインループをランダム表示にする(pre_get_posts)

カテゴリーページなどのアーカイブをランダム表示にするには、まず記事を表示するテンプレート(index.phparchive.php 等)にループを用意します。一覧の各記事は h2 以下の見出しにします(1ページに h1 を複数置かないため)。

PHP:記事一覧のループ(index.php / archive.php 等)
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
  <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
  <?php the_content(); ?>
<?php endwhile; else : ?>
  <p>記事が見つかりませんでした。</p>
<?php endif; ?>

次に functions.php で、pre_get_posts を使ってアーカイブのメインクエリだけ表示順をランダムにします。

functions.php:アーカイブをランダム表示
function my_random_archive($query) {
  // 管理画面・サブクエリ・メインでないクエリは対象外(誤動作防止)
  if (is_admin() || !$query->is_main_query()) {
    return;
  }
  if ($query->is_archive()) {
    $query->set('orderby', 'rand'); // 表示順をランダムに
  }
}
add_action('pre_get_posts', 'my_random_archive');
is_admin()is_main_query() のガードは必須
pre_get_posts管理画面の投稿一覧やサイドバーのサブクエリなど、あらゆるクエリで実行されます。ガードを入れないと管理画面の並び順まで壊れるため、必ず対象を絞ってください。is_archive()is_home() に変えればトップページ、is_category() なら特定カテゴリーだけ、のように調整できます。

WP_Query でランダムな記事一覧を取得する

固定ページの中に記事一覧を差し込みたい場合などは、メインループではなく WP_Query でループを作ります。最後に wp_reset_postdata() でリセットするのを忘れないようにします。

PHP:WP_Query でランダム表示
<?php
$args = array(
  'orderby'        => 'rand', // ランダム表示
  'posts_per_page' => 5,      // 表示件数
);
$random_query = new WP_Query($args);

if ($random_query->have_posts()) :
  while ($random_query->have_posts()) : $random_query->the_post(); ?>
    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    <?php the_content();
  endwhile;
else : ?>
  <p>記事が見つかりませんでした。</p>
<?php endif;
wp_reset_postdata(); // メインループに影響しないようリセット
?>

カテゴリーを絞ってランダム表示する

特定カテゴリーの中からランダムに表示するには、category_name(スラッグ)または cat(ID)を加えます。

PHP:カテゴリー指定+ランダム
$args = array(
  'category_name'  => 'news', // カテゴリースラッグ(IDなら 'cat' => 5)
  'orderby'        => 'rand',
  'posts_per_page' => 3,
);
$query = new WP_Query($args);

カテゴリーの取得や絞り込みの全体像は記事のカテゴリーを取得する方法(WP_Query 対応)、複雑な条件での取得はWP_Queryで複雑な条件検索を実装する方法も参考になります。

ORDER BY RAND() のパフォーマンスに注意

ランダムソートは重い
orderby => 'rand' は内部で ORDER BY RAND() を実行します。これは全行に乱数を割り当ててソートするため、記事数が多いサイトでは負荷が大きく、ページ表示のたびにDBへ問い合わせが走ります。表示件数を絞る結果をキャッシュする、のどちらか(または両方)を必ず併用してください。

下のようにトランジェントAPIでランダムな結果を一定時間キャッシュすれば、毎回 ORDER BY RAND() を実行せずに済み、後述の重複問題も同時に防げます。

PHP:ランダムな投稿をトランジェントでキャッシュ
<?php
// ランダムな投稿を1時間キャッシュ(毎回の ORDER BY RAND() を回避)
$random_posts = get_transient('random_posts');

if ($random_posts === false) {
  $random_posts = get_posts(array(
    'orderby'     => 'rand',
    'numberposts' => 5,
  ));
  set_transient('random_posts', $random_posts, HOUR_IN_SECONDS); // 1時間
}

foreach ($random_posts as $post) {
  setup_postdata($post); ?>
  <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php }
wp_reset_postdata();

2ページ目以降で記事が重複する問題と対処

ランダム表示には構造的な弱点があります。ページを読み込むたびに並び順が変わるため、ページネーションすると2ページ目以降に1ページ目と同じ記事が再び現れることがあります。これは ORDER BY RAND() がリクエストごとに別の順序を返す仕様によるものです。

重複を防ぐ3つの方針

  • キャッシュで順序を固定:上のトランジェント方式なら、キャッシュ期間中は同じ順序になり重複しません(実用上おすすめ)
  • ページネーションせず少数を表示:「おすすめ記事5件」のような用途なら posts_per_page を小さくして1ページに収める
  • 全件を1ページにposts_per_page => -1 で全記事を表示(※記事数が多いと重いので小規模サイト向け)

そもそもページネーションが目的なら、ランダムではなく通常の並び順にしてプラグインなしのページネーション実装方法を使うのが安全です。全記事の一覧化は全記事一覧ページを作成する方法、関連記事のランダム表示はプラグインなしで関連記事を表示する方法も合わせてご覧ください。

よくある質問(FAQ)

QWordPressで記事をランダムに表示するには?
AWP_Query の引数に 'orderby' => 'rand' を設定します。例:new WP_Query(["orderby" => "rand", "posts_per_page" => 5]);。アーカイブ全体をランダムにするなら pre_get_posts$query->set('orderby', 'rand') を使います。
Qランダム表示とキャッシュを両立させるには?
Aget_transient() / set_transient() で結果をキャッシュします。$posts = get_transient("random_posts"); if ($posts === false) { $posts = get_posts(["orderby"=>"rand","numberposts"=>5]); set_transient("random_posts", $posts, HOUR_IN_SECONDS); } で1時間キャッシュでき、毎回の ORDER BY RAND() を避けつつ順序も安定します。テーマやプラグインのキャッシュ機能を使っている場合は、対象ページを除外設定が必要なこともあります。
Qカテゴリーを指定してランダム表示するには?
AWP_Querycategory_name(スラッグ)または cat(ID)と orderby を組み合わせます。例:new WP_Query(["category_name" => "news", "orderby" => "rand", "posts_per_page" => 3]);

まとめ

  • アーカイブ全体pre_get_postsorderby => randis_admin()等のガード必須)
  • 任意の場所WP_Querywp_reset_postdata()
  • パフォーマンスORDER BY RAND() は重い → 件数を絞る+トランジェントでキャッシュ
  • 重複対策:キャッシュで順序固定が実用的。ページネーションが目的なら通常順+ページネーションを使う

ランダム表示は手軽ですが負荷と重複に注意が必要です。キャッシュと表示件数を調整して、軽快に動くランダム表示を実装してみてください。