【ギャラリーサイトで重複しない画像をランダム表示させる時に使った】WordPressで投稿を取得する際に「ORDER BY」節を付ける

WordPressのフィルターフック「posts_orderby」を使うと、投稿を取得するSQLクエリに「ORDER BY」節を加えることができます。私の場合は、ギャラリーサイト制作の時に使いました。

無限スクロールができて、スクロールするたびにどんどん写真が表示される、みたいなギャラリーサイト。その際「重複しないランダムな写真を次々に表示」させるために必要でした。イメージですと、今制作中の「大英図書館Lovers」のサイトが最も近い動作です。

スクロールするたびに重複させずに写真をランダム表示

というわけで、今後もちょくちょく使いそうなので「posts_orderby」の動きについてメモ書きました。(ランダムで重複させない方法については需要がありましたらまた後日にでも・・・)まずは基本形を書いて覚えておこう!ということで、もし興味がありましたらご参考ください。

サンプルコードを見てみよう

Codexにサンプルがありましたので「posts_orderby」について見てみます。

add_filter('posts_orderby', 'edit_posts_orderby');
add_filter('posts_join_paged','edit_posts_join_paged');

function edit_posts_join_paged($join_paged_statement) {
	$join_paged_statement = "LEFT JOIN wp_gdsr_data_article gdsra ON gdsra.post_id = wp_posts.ID";
	return $join_paged_statement;	
}

function edit_posts_orderby($orderby_statement) {
	$orderby_statement = "(gdsra.user_votes_total_sum/gdsra.user_votes_count) DESC";
	return $orderby_statement;
}

サンプルコードはフィルターフックが2つ登場していますね。

  • 「posts_orderby」 → 「ORDER BY」節追加のフィルターフック
  • 「posts_join_paged」 → post 配列を返すクエリの JOIN 節に対し、ページングが計算された後適用される(ページング自体は JOIN に影響しないので、このフィルターは posts_join と実質的には同一)。※フィルターフック一覧より

やっていること

コードが少し難しく見えますが、やっていることは単純です。

LEFT JOINで結合しているテーブル「wp_gdsr_data_article」はWordPressの記事を評価付ける「GD Star Rating」プラグインを使っていたら作られるテーブルですね。そのテーブルを「posts_join_paged」にフックさせています。

で、今回話題にしている「ORDER BY」節「(gdsra.user_votes_total_sum/gdsra.user_votes_count) DESC」をさらに「posts_orderby」にフックさせています。

要は「SQLクエリにフックして、取得できる投稿を変えられるよ」ってことが私はわかりました。関連するフィルターフックは他にもあって、

  • post_limits
  • posts_distinct
  • posts_where

などなど。一部だけご紹介しましたので、詳細は「フィルターフック一覧」をご確認ください。

まとめ

他のテーブルと結合して&ソートして投稿を出力とか、私は割と使います。そんな時に調べていると「posts_orderby」を知りましたので使っています。もしかしたら「WP Query」「pre_get_posts」とかでも似たようなことできるのかな。また時間を見てやってみますね。

著者:bouya Imamura