私はWordpressのサポートでこの問題を発見し、残念ながらこのトピックは現在終了しています。私はこれと同じ問題を抱えています...(下記を参照)
私たちはメンバーが好きな本、映画、歌などのようなものを推薦できるサイトを作成しました。この問題のために私は例として映画ページを使います。
"Movies"ページは、最終的には "press"というカテゴリに分類されたすべての投稿のランダムなリストを表示するようWordpressに要求するカスタムページテンプレートです。以下のコードを使用して、これらの映画のタイトルをランダムな順序で表示します。
<?php
$Rand = new WP_Query("cat=31&showposts=-1&orderby=Rand");
while($Rand->have_posts()) : $Rand->the_post();
?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?>
<?php endwhile; ?>
問題は、リストがかなり長くなりすぎているので、私はそれをそれぞれ約10本の映画の2ページ以上に分割したいと思います。これを達成するために、私は以下のコードを使いました。
<?php
$page = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts("cat=31&orderby=Rand&showposts=10&paged=$page");
while ( have_posts() ) : the_post()
?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?>
<?php endwhile; ?>
しかし、それはデータをそれぞれ10の投稿のページに分割しますが(ページネーション)、ページ2などに10の投稿の新しいセットを含めることができないため、問題があります。言い換えれば、それは物事をランダムな順序でリストしているので、それはちょうど出て行き、さらに10個のランダムな投稿(またはこの場合は映画のタイトル)を取得します。その結果、2ページ目に10個のランダムな映画タイトルの新しいセットの代わりに、映画タイトルの投稿が繰り返されています。
私の質問は - 私はそれが1ページに含まれているランダムな10の投稿を「記憶」し、それから2、3などに配置するために10の投稿の新しいセットを取得するようにするためのものです。すべての投稿が表示されます。 10のセットにランダムにソートされた場合、私は1ページにつき1回の投稿しか発生しないことを望みます。
WP_queryのORDER BYステートメントを変更するためにフィルターを使用できます。
そうすれば、ORDER BY Rand($ seed)を使用するように手動でクエリを設定できます。
Mysql Rand()はシードをオプションの引数として受け入れます。シードを使用すると、毎回同じランダム化された結果セットが返されます。
そのため、最初のページの読み込み時に乱数を生成してSESSION変数に格納し、それをさらにページ付けされたリクエストの$ seedとして使用できます。
あなたが例えばあなたのメインループでこれを達成しようとしているなら、あなたはあなたのfunctions.phpファイルに以下を追加することができます。
session_start();
add_filter('posts_orderby', 'edit_posts_orderby');
function edit_posts_orderby($orderby_statement) {
$seed = $_SESSION['seed'];
if (empty($seed)) {
$seed = Rand();
$_SESSION['seed'] = $seed;
}
$orderby_statement = 'Rand('.$seed.')';
return $orderby_statement;
}
WordPressの最後のバージョン以降、WP_Query
のorderby
パラメーターの値にシードを追加できるようになりました。
$query = new WP_Query([
'orderby' => 'Rand($seed)',
...
]);
$seed
は乱数です。 PHPセッション変数として保存する必要があります。 functions.php
でsession_start()
を呼び出して、PHPでWordPressセッションを有効にすることを忘れないでください。
if (!session_id()) {
session_start();
}
この構文では、posts_orderby
フィルターを使用する必要はありません。さらに、フィルターが対象のWP_Queryにのみ適用されることを確認する必要はありません。
詳細については、 this ticket on WordPress Coreをご覧ください。