- 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細)
テンプレートタグ/query posts
query_posts()はWordPressが投稿を表示するのに使用しているメインクエリーを置き換える手段です。これはメインクエリーを一旦横に置いておき、新しいクエリーで上書きします。query_postsを呼び出したあとは、クエリーの改変を戻すために、wp_reset_query()を呼び出し、オリジナルのメインクエリーを復活させる必要があります。
query_postsを使うことによって、ページ上のメインクエリーが置き換えられ、ページの読み込み速度に影響を与えることに留意してください。最悪の場合、倍かそれ以上の処理が発生します。簡単に使える代わりに、この関数は混乱と問題を引き起こす傾向があります。下記の注意をご覧ください。
一般的な投稿の取得には、WP_Queryか、get_postsを使ってください。
query_postsではなくpre_get_postsフィルターを用い、is_main_queryでチェックしてメインクエリーを変更することが強く推奨されています。
たとえば、ホームで、通常最新の10件の投稿が表示されているとします。もし5件だけ表示したいのであれば、query_posts()を使ってこのように書くことができます(ページ送りについては無視しています)。
query_posts( 'posts_per_page=5' );
functions.phpでpre_get_postsを使って同じことをするなら、このように書けます。
function five_posts_on_homepage( $query ) { if ( $query->is_home() && $query->is_main_query() ) { $query->set( 'posts_per_page', '5' ); } } add_action( 'pre_get_posts', 'five_posts_on_homepage' );
注意:pre_get_postsアクションは固定ページのリクエストでは動作しません。
注意
query_posts()はデータベースに問い合わせて投稿の一覧を生成するための、数ある方法のひとつに過ぎません。query_posts()を使うと決める前に、欠点も理解しておいてください。
メインループを変更する
query_posts()はメインループを変更するためのものです。query_posts()はそのために、メインループを生成するクエリーを置き換えます。いったんquery_posts()を使うと、投稿にもとづいたグローバル変数やテンプレートタグも変更されます。query_posts()を呼び出したあとは、条件分岐タグも置き換えられてしまいます。このことが意図しない結果を引き起こすかもしれません。
派生的なループ
派生的な一覧 (例えばページの下部に関連記事を表示したり、サイドバーのウィジェットでリンクの一覧を出したり等) を表示したい場合は、WP_Queryの新しいインスタンスを生成するか、get_posts()を使ってください。
もしquery_posts()を使う場合は、用が済んだら必ずwp_reset_query()を呼び出してください。
ページ送り
'paged' クエリー引数を適切に指定していないと、ページ送りが正しく動作しない可能性があります:英語版Codex "adding the paged parameter"を参照してください。
SQLクエリーが追加発行される
query_postsをテンプレートで使用する場合、WordPressはすでにデータベースへの問い合わせを実行し、テンプレートを読み込む頃にはデータの取り出しを終えています (なぜなら、どのテンプレートが読み込まれるかが決まったということは、すでに処理が終わっているということですから!)。そのため、query_posts()を使ってデフォルトのクエリーを上書きして結果を得るには、どうしても再度データベースに問い合わせし再計算する必要があります。
このことは、小規模なブログベースのウェブサイトを扱っているのであれば、必ずしも問題であるとは言えません。データベースが大きい大規模でトラフィックの多いウェブサイトの開発者であれば、デフォルトのクエリーが呼び出される前に直接変更するなどの代替案を検討するほうがいいかもしれません。requestフィルターでまさにこれを実現できるでしょう。
'parse_query' と 'pre_get_posts' フィルターも内部的に $query オブジェクトを改変しデータベースへ問い合わせるSQLを生成するのに使われます。
使い方
<?php // クエリ query_posts( $args ); // ループ if ( have_posts() ) : while ( have_posts() ) : the_post(); echo '<li>'; the_title(); echo '</li>'; endwhile; else: endif; // クエリをリセット wp_reset_query(); ?>
オリジナルクエリの保持(ページングなど)
デフォルトでは query_posts を実行すると、引数で指定した変数を除きページング,カテゴリー,日付などの現在のページのクエリ変数はすべて上書きされます。この時、オリジナルのクエリを保持したい場合は、query_poats() の引数にグローバル変数である $query_stringを用いることができます。
例えば、残りの投稿文字列に影響をおよぼすこと無く投稿の表示順を保持する時、ループの前に下記を記述することができます。
global $query_string; query_posts( $query_string . '&order=ASC' );
query_posts() をこのように用いる時、''で囲まれたパラメーターはアンド記号 & で始まる必要があります。
あるいは、元のクエリ配列を引数配列に統合することもできます。
global $wp_query; $args = array_merge( $wp_query->query, array( 'post_type' => 'product' ) ); query_posts( $args );
引数の組み合わせ
引数はアンド記号 (&) を使って複数組み合わせて指定することができます:
query_posts( 'cat=3&year=2004' );
「最新の投稿」ページで、カテゴリー ID が 13 かつ今月の投稿を表示する場合:
if (is_home()) { query_posts( $query_string . '&cat=13&monthnum=' . date( 'n', current_time( 'timestamp' ) ) ); }
バージョン 2.3 で、カテゴリー ID 1 と 3 に含まれる投稿を2件、タイトルの降順で表示する場合:
query_posts( array( 'category__and' => array(1,3), 'posts_per_page' => 2, 'orderby' => 'title', 'order' => 'DESC' ) );
カテゴリー ID が 1 で "apples" のタグ付けがされた投稿を表示する場合:
query_posts( 'cat=1&tag=apples' );
複数のタグを同時に指定する場合は「+」を用います。下記はカテゴリー ID が 1 で、"apples"と"oranges"のタグがついた投稿を表示します:
query_posts( 'cat=1&tag=apples+oranges' );
パラメーター
ここでの記述例は WP_Query オブジェクトでも使えるものですが、もちろんこれが全てではありません。パラメーターを組み合わせることで、より実用的なクエリが可能になります。パラメーターの詳細はこちらを参照してください。
コード記述例
「最新の投稿」ページから指定カテゴリーを除く
index.php ファイルに以下のコードを書くと、カテゴリー ID が 3 以外の 投稿を表示します。
<?php if ( is_home() ) { query_posts( 'cat=-3' ); } ?>
複数のカテゴリー ID を指定できる(バージョン 3.3.1 で検証済)。
<?php if ( is_home() ) { query_posts( 'cat=-1,-2,-3' ); } ?>
特定の投稿を表示
特定の投稿を表示。
<?php query_posts( 'p=5' ); ?>
注:特定の投稿が「添付」の場合、pの代わりにattachment_idを用います。
<?php query_posts( 'attachment_id=5' ); ?>
続きを読む を表示したい場合は、グローバル変数 $more を 0 にします。
<?php // 投稿 ID が 5 の投稿を表示する query_posts( 'p=5' ); // 投稿の始めの部分のみ表示するため $more を 0 にする global $more; $more = 0; // ループ while (have_posts()) : the_post(); the_content( 'Read the full post »' ); endwhile; ?>
2008年5月に投稿された、カテゴリー ID 1 と 3 の投稿タイトルを1ページに5件ずつ表示する:
<?php if (have_posts()) : query_posts('posts_per_page=5&cat=1,3&monthnum=5&year=2008'); ?> <?php while (have_posts()) : the_post(); ?> <?php the_title(); ?> <?php endwhile; endif; ?>
カテゴリー ID 2 と 6 のいずれにも含まれないすべての投稿のタイトルをリストとして表示する:
<?php if (have_posts()) : query_posts(array('category__not_in' => array(2,6))); ?> <ul> <?php while (have_posts()) : the_post(); ?> <li><?php the_title(); ?></li> <?php endwhile; endif; ?> </ul>
カテゴリーの全投稿
管理画面の「設定」→「表示設定」で設定する「1ページに表示する最大投稿数」のパラメーターが適用されます。これを上書きするためには、 'post_per_page' パラメーターを設定します。以下が例です:
query_posts( array ( 'category_name' => 'my-category-slug', 'posts_per_page' => -1 ) );
これにより、指定されたカテゴリーの全ての投稿を表示させます。
しかし、サブカテゴリーまたは子カテゴリーでは「カテゴリー名」が常に使えるとは限らないため、「カテゴリースラッグ」を用いる方が良いとされます。詳しくは、 is_category() を参照してください。
if (is_category('category-slug')): query_posts(array('category_name' => 'my-category-slug', 'posts_per_page' => -1 )); endif;
RSS/Atom フィードで表示する最新の投稿数
管理画面の「設定」→「表示設定」で設定する「RSS/Atom フィードで表示する最新の投稿数」または 'posts_per_rss' パラメーターは、フィードで使われるクエリーの 'posts_per_page' パラメーターを上書きします。
これをさらに上書きするため (例えば全ての適合する投稿を必要とするカスタムしたICSフィード等) には、以下のように "post_limit" フィルターを用います:
if ( isset ( $query->query_vars['feed'] ) and ( $query->query_vars['feed'] == 'ics' ) ) { add_filter( 'post_limits', '__return_empty' ); }
query_posts に変数を与える
query_posts に変数を与える方法をいくつか紹介します。どれを使用してもかまいませんので、必要に応じてWordPress ループ の前に記述してください:
記述例 1
この例は、query_posts を実行する前にクエリ文字列を連結します。まず変数に値を代入し、次に変数と文字列を結合して、実行します。ここではカテゴリー ID を変数で与えることにします。
// 現在のカテゴリー ID を変数に代入 $categoryvariable = $cat; // クエリを連結 $args = 'cat=' . $categoryvariable . '&orderby=date&order=ASC'; // クエリを実行 query_posts( $args );
記述例 2
次の例では、二重引用符を使って PHP に式を評価させます。まず、現在の年・月を表示し、query_posts で公開日が現在の年・月に該当する投稿を表示します。投稿の並び順は日付の昇順で、公開日の古い順に表示します。
$current_year = date('Y'); $current_month = date('m'); query_posts( "cat=22&year=$current_year&monthnum=$current_month&order=ASC" );
記述例 3
この例では、ページネーションを使ってすべての投稿を表示する場合を説明します。デフォルトの $query_string を使って query_posts ですべての投稿を表示させることができます。posts_per_page の値には -1 か各ページに表示したい投稿の数を指定します。後者の場合には posts_nav_link() でページを移動する手段を提供しましょう。
query_posts( $query_string . '&posts_per_page=-1' );
記述例 4
$query_string 変数を使わずに、引数を配列に入れる方法もあります。例えば、記述例 2 のクエリは以下のようになります:
$args = array( 'cat' => 22, 'year' => $current_year, 'monthnum' => $current_month, 'order' => 'ASC' ); query_posts( $args );
この方法は、変数ごとに1行ずつ記述すると読み易くなります。
記述例 5
記述例 4で示した配列を複数のタクソノミーに入れることも可能です。これは単純にタクソノミーのスラッグをコンマで分割した文字列として代入するだけです。この例では、植木等または高倉健が出演している映画の投稿を全て抽出します。
$args = array( 'post_type'=> 'movie', 'actor' => 'Hitoshi Ueki, Ken Takakura', 'order' => 'ASC' ); query_posts( $args );
変更履歴
1.5.0から導入されました。
ソースファイル
query_posts() は wp-includes/query.php
にあります。
リソース
- Advanced Taxonomy Queries in WordPress 3.1
- Change Order for Custom Post Types in WordPress 3.0
- Perishable Press - 6 Ways to Customize WordPress Post Order
- nietoperzka's Custom order of posts on the main page
- Displaying related category and author content
- Exclude posts from displaying
- Taxonomy Intersections and Unions for WordPress 2.3
- If..Else - Make WordPress Show Only one Post on the Front Page
- If..Else - Query Posts in WordPress 1.5
最新英語版: WordPress Codex » Template Tags/query posts (最新版との差分)
関連
記事
- 記事: ループ - WordPress ループ内でのクエリの使い方に関する基本的な概要。
- 記事: クエリ概要 - どのクエリが WordPress を生成するのかが決定される方法についての説明。
- 記事: フックを使ったクエリのカスタマイズ
- 記事: カスタムセレクトクエリを使った投稿の表示 /en
- 記事: 高度なタクソノミークエリの生成 /en
- 記事: オフセットとページネーションを活用したカスタムクエリ /en
コード・ドキュメンテーション
- クラス: WP_Query - WP_Query クラスの詳細な全容
- クラス: WP_Comment_Query - コメント関連のクエリのためのクラス
- クラス: WP_User_Query - ユーザー関連のクエリのためのクラス
- オブジェクト: $wpdb - $wpdb オブジェクトの使い方全容
- 関数: set_query_var()
- 関数: get_query_var()
- 関数: query_posts() - 追加のカスタムクエリを作成
- 関数: get_post() - 項目の ID を取得しデータベース内にあるその投稿のレコードを返す
- 関数: get_posts() - 投稿の配列を返すことに特化した関数
- 関数: get_pages() - ページの配列を返すことに特化した関数
- 関数: have posts() - クエリが投稿を返すか否かを判断する条件関数
- 関数: the_post() - クエリ後に自動的にループを設定する
- 関数: rewind_posts() - 現状のループをリセットする
- 関数: setup_postdata() - ループ内で個別の結果を得るためのクエリデータを設定する
- 関数: wp_reset_postdata() - 直前のクエリを復元する (通常はループ内の別のループの後に用いられる)
- 関数: wp_reset_query()
- 関数: is_main_query() - 変更されるクエリがメインのクエリであることを確認する
- アクションフック: pre_get_posts - WordPressクエリが実行される前に変更する
- アクションフック: the_post - post クエリの後で post オブジェクトを変更する
- フィルターフック: found_posts - WP_Query オブジェクトの found_posts 値を変更する