WordPress 日毎でランダムな記事を表示

以前、WordPress のフォーラムに「日毎でランダムな記事を表示したい」というような内容のトピックが上がっていたので、投稿を取得するパラメーターの orderby にシード値として日付を指定した RAND を使用する方法を提案しました。

$seed = date_i18n( 'Ymd' );
$the_query = new WP_Query( array(
	'post_type' => 'post',
	'posts_per_page' => 1,
	'orderby' => "RAND($seed)",
) );

これは、MySQL における RAND 数学関数のシード値が同じ場合、毎回同じ値を返すことを利用したものです。

トピックとしてはこれで解決はしたのですが、投稿数(レコード数)が変わると同じシード値でも異なる値が返される場合があるため、厳密ではありませんでした。

そこで、ここでは厳密に日毎の投稿を表示する方法を紹介します。

処理としては、WordPress の Transients API を利用して、その日限定(24:00 まで有効)の値(投稿 ID の配列)をデータベースに作成する方法です。

まずは、下記コードを functions.php に追加します。

/**
 * 日毎(ローカル時間 24:00 に切り替え)のランダム投稿を取得します。
 *
 * @param int $count
 * @return array List of posts.
 */
function get_posts_daily_random( $count = 1 ) {
	$transient = 'my_daily_random_posts';
	$ids = get_transient( $transient );
	if ( $ids === false ) {
		mt_srand( strtotime( date_i18n( 'Y-m-d H:i:s' ) ) );
		$ids = get_posts( array(
			'fields' => 'ids',
			'post_type' => 'post',
			'posts_per_page' => $count,
			'orderby' => 'RAND(' . mt_rand() . ')',
		) );
		if ( $ids ) {
			$sec = strtotime( date_i18n( 'Y-m-d 24:00:00' ) ) - strtotime( date_i18n( 'Y-m-d H:i:s' ) );
			set_transient( $transient, $ids, $sec );
		}
	}
	if ( $ids !== false ) {
		return get_posts( array( 'post__in' => $ids ) );
	}
	return array();
}

あとは、テンプレートで、get_posts_daily_random 関数を呼び出すだけです。戻り値は 投稿オブジェクトの配列(get_posts と同じ)です。

<ul>
<?php
$myposts = get_posts_daily_random();
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
	<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach;
wp_reset_postdata(); ?>
</ul>

コメントを残す

メールアドレスが公開されることはありません。

日本語でコメントを入力してください。(スパム対策)