047
メインループのクエリ条件を正しい方法で変更する
Library
たとえば投稿の一覧を表示するとき、新しい順ではなく古い順で表示したり、特定の投稿を除外したりするには、クエリ条件を変更する必要があります。ところが、テンプレートが読み込まれた時点ですでにクエリ(データベースから投稿を取得してくる処理)は終了しているため、後から変更することはできません。メインループのクエリ条件を変更するには、pre_get_postsというアクションフックを利用します。
| 用例 |
|
|---|---|
| 関連 | |
| Codex |
処理順を簡単に理解する
index.phpを含むアーカイブ系テンプレートで投稿の一覧を表示したり、single.phpなどで投稿そのものを表示したりする際、WordPressは自動的にクエリ(データベースへの問い合わせ)を行い、テーマ作成者がデータベースを意識しなくてもよいようになっています。
- ユーザがリンクをクリックしてページを表示する
- WordPressがデータベースに対し、ページに応じた適切なクエリを行い、投稿を表示する準備を行う
- テンプレートファイルの処理が開始される
したがって、index.phpやsingle.phpのようなテンプレートファイルでは、メインループのクエリ条件を変更することはできません。
query_posts()は使わない!
メインループのクエリ条件を変更する手段として、query_posts()を使用してはいけません。この関数はテーマ内、あるいはプラグイン内で使われることを想定されたものではありません。もしWordPressの解説サイトなどでこの関数を見かけたとしても、使わないよう注意してください(Codexの説明の1行目に書いてあります)。
メインループのクエリを操作するためのアクションフック
投稿を取得する前に実行されるpre_get_posts()というアクションフックを使えば、クエリ条件を変更することができます。このアクションフックは上の処理順において、1の後、2の前に位置します。
このアクションフックは、is_main_query()という、メインクエリ(メインループのためのクエリ)かどうかを判定する関数とともに使用することが推奨されています。
たとえば、投稿の一覧を新しい順ではなく古い順に表示したい場合、functions.phpに次のように記載します。
function twpp_change_sort_order( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'twpp_change_sort_order' );'order'というパラメータは、デフォルトでDESC(降順)になっていますが、これをASC(昇順)にすることで、日付が古い順に並びます。$query->set()には様々なパラメータを指定することができ、ありとあらゆるクエリ条件を実現することができます。追って解説を加えていきますが、どのようなパラメータがあるかすぐに知りたい方はCodexを参照してください。
なお、上の処理は実用上、あまり適切とは言えません。カテゴリーページや日付アーカイブページなどすべてが古い順になってしまうだけでなく、管理画面の投稿一覧も反転します。
そこで、表示順の反転を投稿ページに限定し、かつ管理画面では動作しないよう条件を加えておきます。
function twpp_change_sort_order( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_home() ) {
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'twpp_change_sort_order' );is_admin()は管理画面かどうかを判定する関数、is_home()は投稿ページかどうかを判定する関数です。これらの説明はここでは割愛します。
Comment