取得したい記事をかなり自由に指定できるWP_Query。WordPressで必須知識と言っても過言ではないでしょう。

しかし、WP_Queryは万能だからこそ、覚えることが多すぎる!
全部は覚えてはいられず、いつもググりながら使用していました。指定したIDのタグのいずれかを含む投稿を取得できる。

そこで、一旦整理してみようと思って色々調べたことをまとめていこうと思います。

目次

WP_Queryの基本の使い方

とりあえず基本的な使い方。いつもこれをコピペしてから引数をいじってます。

<?php
//$argsの中身を変えていく
$args = array(
    'post_type' => 'post', 
    'posts_per_page' => -1
 );

$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
  while ($the_query->have_posts()) : $the_query->the_post();

  //ループ内記述

  endwhile;
endif;
wp_reset_postdata();
?>

配列$argsに取得したい記事に関する情報を入れ、WP_Queryを呼び出してループさせます。'posts_per_page' はこの後にもメモしていますが、1ページにループさせる回数です。(-1で全てループ)

予期せぬエラーを防止するため、ループが終われば wp_reset_postdata() で情報をリセットしておくのを忘れずに。

基本的なパラメータ

投稿タイプ・投稿ステータスの指定

投稿のタイプやステータスを指定する方法について。

記述例

$args = array(
  'post_type' => 'post',      //投稿タイプの指定
  'post_status' => 'publish'  //投稿ステータスの指定
);

以下、順に説明します。

'post_type' (string / array)
投稿タイプを指定。デフォルト値は 'post'。複数指定する場合は配列で指定します。
*: 'tax_query' がクエリーにセットされている場合、デフォルト値は 'any' になります。
指定できる値は以下の通りです。
'post' 投稿
'page' 固定ページ
'revision' 履歴 (リビジョン)
'attachmen' 添付ファイル。
添付ファイルは投稿ステータスがデフォルトで 'inherit' になっているので、 後述する'post_status'パラメータを明示的に'inherit''any'にしなければ、添付ファイルは取得できないことに注意。
'pnav_menu_item' ナビゲーションメニュー項目
'any' リビジョンと 'exclude_from_search'パラメータ が trueにセットされたものを除き、すべてのタイプを含める。
'カスタム投稿タイプ' 任意のカスタム投稿タイプ名
'post_status' (string / array)
投稿ステータスを指定。 デフォルト値は 'publish'だが、ユーザーがログイン中なら 'private'もデフォルト値に追加される。
*:さらに管理画面のコンテキストでクエリが動作中なら(管理画面または AJAX 呼び出し)、保護状態のステータスも追加されます。デフォルトでは保護状態のステータスは 'future', 'draft' と 'pending' です。
指定できる値は以下の通りです。
'publish' 公開された投稿もしくは固定ページ
'pending' レビュー待ちの投稿
'draft' 下書きの投稿
'auto-draft' コンテンツのない、新規作成された投稿
'future' 予約公開設定された投稿
'private' ログインしていないユーザーからは見えない投稿
'inherit' リビジョン
'trash' ゴミ箱に入った投稿
'any' 'trash' と 'auto-draft' を除き、すべてのステータスの投稿

投稿・固定ページの指定

特定の投稿や固定ページを直接指定する方法について。

記述例

$args = array(
  'p' => 10,                    //投稿IDの指定
  'name' => 'post-slug',        //投稿スラッグの指定
  'page_id' => 12,              //固定ページIDの指定
  'pagename' => 'page-slug',    //固定ページスラッグの指定
  'post_parent' => 15,          //親IDの指定
  'post__in' => array(5,8,11),  //投稿IDを配列で指定
  'post__not_in' => array(3,6)  //省きたい投稿のIDを配列で指定
);

以下、順に説明します。

'p' (int)
投稿IDを指定。
'name' (string)
投稿のスラッグを指定。
'page_id' (int)
固定ページのIDを指定。
'pagename' (string)
固定ページのスラッグを指定。
子ページを表示するには、スラッシュで区切られた親と子のスラッグを指定する。
'post_parent' (int)
固定ページの親IDを指定。子ページを返す。
'post__in' (array)
投稿IDを配列で複数指定。
'post__not_in' (array)
省きたい投稿IDを配列で指定。

並び順の指定

取得した記事のループの順番を指定する方法について。

記述例

$args = array(
  'order' => 'ASC',  //昇順・降順の指定
  'orderby' => 'ID'  //何順に並べるかの指定
);

以下、順に説明します。

'order' ('ASC' / 'DESC')
昇順・降順のどちらで並び替えるかを指定 (デフォルト値は降順の'DESC')。
'ASC' 最低から最高へ昇順 (1, 2, 3), (a, b, c)
'DESC' 最高から最低へ降順 (3, 2, 1), (c, b, a)
'orderby' (string / array)
パラメータで指定した項目の値で投稿をソートする。デフォルトは 'date'。配列で2つ以上のオプションを含めることもできます。
指定できる値は以下の通りです。
'none' 順序をつけない
'ID' 投稿IDで並び替え
'author' 著者で並び替え
'title' タイトルで並び替え
'date' 日付で並び替え
'modified' 更新日で並び替え
'parent' 投稿/固定ページの親ID順で並び替え
'rand' ランダムで並び替え
'comment_count' コメント数で並び替え
'menu_order' 固定ページの表示順で並び替え。
固定ページと添付ファイル(ギャラリー内のメディアの順番に相当)で使うことが最も多い。バラバラの値が入った 'menu_order' を持つ任意の投稿タイプに対しても使うことができる(デフォルト値は 0)。
'meta_value' カスタムフィールドの値で並び替え。'meta_key=keyname' がクエリに存在しなければいけません。
ソート順は文字列順になることに注意。
'meta_value_num'' カスタムフィールドを数値順で並び替え。'meta_key=keyname'がクエリに存在しなければいけません。
'post__in' 'post__in'パラメータの配列に並んだ投稿 ID の順に並び替え

ページ送りの指定

ページャーに関するパラメータを指定する方法について。

記述例

//現在のページから投稿を表示するが、もしクエリ変数がセットされていなければ(先頭ページなら)パラメータに1をセット
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;

$args = array(
  'posts_per_page' => 10,           //取得する投稿数の指定
  'posts_per_archive_page' => 20,   //取得する投稿数の指定(アーカイブ専用)
  'paged' => $paged,                //現在のページ番号の指定
  'offset' => 3,                    //オフセット数の指定
  'nopaging' => false,              //ページ送りを使用しないかどうか
  'page' => $paged,                 //静的フロントページ用のページ番号の指定
  'ignore_sticky_posts' => false    //先頭固定表示を無視するかどうか
);

※静的フロントページに指定したページテンプレートにおいて、ページ送りに対応させるには get_query_var( 'page' )を使う('paged'ではなく'page'です)。クエリ変数 'page'は、クイックタグ をコンテンツに含んでおり、ページ分割された単一の投稿または固定ページについて、ページ番号を保持します。
例: $paged = ( get_query_var('page') ) ? get_query_var('page') : 1;

以下、順に説明します。

'posts_per_page' (int)
1ページに含める投稿数。'posts_per_page' => -1 とすると全ての投稿を含めます(このとき'offset'パラメータは無視されるので注意)。
ページ送りを使用する場合はこのパラメータと一緒に'paged'パラメータを指定。ページ送りを使用しない場合でもこのパラメータは使えます。
このパラメータは、フィードでのクエリ(is_feed()がtrue)の場合、get_option('posts_per_rss')の値(RSS/Atom フィードで表示する最新の投稿数)で上書きされます。フィードでも投稿数を指定するには 「post_limitsフィルター」を使うか、「pre_option_posts_per_rssフィルター」で -1 を返す必要があります。
'posts_per_archive_page' (int)
1ページに含める投稿数。アーカイブページ専用で使用できます。
is_archive()is_search()が true になるページでは、'posts_per_page''showposts'の値を上書きします。
'paged' (int)
現在のページ番号。基本的にget_query_var('paged')を入れて使用する。
'offset' (int)
ずらす(読み飛ばす)投稿の数。
注意:'offset'パラメータをセットすると 'paged'パラメータが無視されます。そのためページ送りされません。
'nopaging' (bool)
すべての投稿を表示するか、ページ送りを使用するか。デフォルト値は'false'(ページ送りを使用する)。
'page' (int)
静的フロントページ用のページ番号。静的フロントページのページ X に表示されるであろう投稿を表示します。(?)
'ignore_sticky_posts' (bool)
先頭固定表示の投稿の優先度を無視するかどうか。デフォルトは'false'でそのまま先頭に表示します。'true'にすると先頭ではなく、通常のページと同様に扱われます。

日付の指定

日付や時間に関するパラメータを指定する方法について。

記述例

$args = array(
  'year' => 2017,    //年の指定
  'mouthnum' => 6,   //月の指定
  'w' => 6,          //週番号の指定
  'day' => 14,       //日の指定
  'hour' => 20,      //時間の指定
  'minute' => 0,     //分の指定
  'second' => 0,     //秒の指定
  'm' => 201706      //年と月で指定
);
'year' (int)
年 (4桁で指定する。例: 2017)
'monthnum' (int)
月 (1 から 12)
'w' (int)
年内の週番号 (0 から 53)。MySQL の WEEK コマンド を使用。
get_option("start_of_week")の値に依存する。
'day' (int)
日 (1 から 31)
'hour' (int)
時 (0 から 23)
'minute' (int)
分 (0 から 60)
'second' (int)
秒 (0 から 60)
'm' (int)
年と月で指定。(例: 201706)

さらに複雑な指定ができるdate_queryに関しては「 その他」でまとめています。

カテゴリ・タグ・タクソノミー

カテゴリの指定

カテゴリに関するパラメータを指定する方法について。

記述例

$args = array(
  'cat' => 5,
  'category_name' => 'info', 'code',
  'category__and' => array( 1, 6 ), //1かつ6
  'category__in' => array( 1, 6 ), //1または6
  'category__not_in' => array( 2, 4 ) //2,4以外
);
'cat' (int)
カテゴリIDを指定。
省きたいものは -(マイナス)を付けて指定。
'category_name' (string)
カテゴリスラッグを指定。
複数の場合は配列ではなく、 ,区切りで指定。
'category__and' (array)
カテゴリIDを配列で指定。
指定したIDのカテゴリを すべて含む投稿を取得できる。
'category__in' (array)
カテゴリIDを配列で指定。
指定したIDのカテゴリの いずれかを含む投稿を取得できる。
'category__not_in' (array)
カテゴリIDを配列で指定。
指定したIDのカテゴリを 含まない投稿を取得できる。

タグの指定

タグに関するパラメータを指定する方法について。

記述例

$args = array(
  'tag_id' => 5,
  'tag' => 'html', 'css',
  'tag__and' => array( 1, 6 ),
  'tag__in' => array( 1, 6 ),
  'tag__not_in' => array( 1, 6 ),
  'tag_slug__and'=> array( 'html', 'css' ),
  'tag_slug__in'=> array( 'html', 'css' )
);
'tag_id' (int)
タグIDを指定。
省きたいものは -(マイナス)を付けて指定。
'tag' (string)
タグのスラッグを指定。
複数の場合は配列ではなく、 ,区切りで指定。
'tag__and' (array)
タグIDを配列で指定。
指定したIDのタグを すべて含む投稿を取得できる。
'tag__in' (array)
タグIDを配列で指定。
指定したIDのタグの いずれかを含む投稿を取得できる。
'tag__not_in' (array)
タグIDを配列で指定。
指定したIDのタグを 含まない投稿を取得できる。
'tag_slug__and' (array)
タグスラッグを配列で指定。
指定したスラッグのタグを すべて含む投稿を取得できる。
'tag_slug__in' (array)
タグスラッグを配列で指定。
指定したスラッグのタグの いずれかを含む投稿を取得できる。

タクソノミーの指定

タクソノミーに関するパラメータを指定する方法について。

記述例

$args = array(
  'tax_query' => array(                      //タクソノミーに関する指定はこの中にすべて
    'relation' => 'AND',                     //条件1,2をどのような関係で指定するか
    //条件1
     array(
        'taxonomy' => 'music',              //タクソノミー名を指定
        'field' => 'id',                    //タームの指定をIDで指定するか、slugで指定するか
        'terms' => array(102, 114, 235),    //タームをIDで指定('field'が'id'なので)
        'operator' => 'AND',                //'terms'をどの関係で指定するか
        'include_children' => false,        //子タクソノミーを含めるかどうか
     ),
     //条件2
     array(
        'taxonomy' => 'movie',
        'field' => 'slug',
        'terms' => 'action',                //タームをスラッグで指定('field'が'slug'なので)
     )
    )
);
'tax_query' (array)
タクソノミーに関するパラメータをまとめる配列。
'tax_query'の値にさらに配列で各パラメータを指定していく。
'taxonomy' (string)
タクソノミーを指定。
'field' ('id' / 'slug')
IDかスラッグのどちらでタームを指定するかを宣言する。
'terms' (int / string / array)
タームを指定。IDで指定するのかスラッグで指定するのかは、'field'パラメータでの宣言に合わせる。
複数指定の場合は配列で指定する。
'operator' ('AND' / 'IN' / 'NOT IN')
指定したタームを全て含む投稿を取得する('AND')か、いずれかを含む投稿を取得する('IN')か、含まない投稿を取得する('NOT IN')かを指定できる。
'terms'が配列のときにのみ有効。
'include_children' (bool)
タクソノミーが階層構造を持っている場合、子タームを含めるかどうか。
デフォルトはtrue
'relation' ('AND' / 'OR')
タクソノミーに関するパラメータ配列を複数指定する場合に、それらすべてに該当する投稿を取得する('AND')か、いずれかに該当する投稿を取得する('OR')かを指定。
'tax_query'パラメータの最初で指定する例がほとんどだが、最後でもOK。

カスタムフィールドの指定

カスタムフィールドに関する指定は2パターンあります。

keyやvalueを一つずつ指定する単純なパターン

パターン1。keyとvalueを単純に一つずつ指定する場合。

記述例

//カスタムフィールドの値が文字列の場合の例
$args = array(
  'meta_key' => 'price',
  'meta_value' => '100円',
  'meta_compare' => '=',
  )

//カスタムフィールドの値が数値(int や double)の場合の例
$args = array(
  'meta_key' => 'number',
  'meta_value_num' => 100,
  'meta_compare' => '>',
  )
'meta_key'(string)
カスタムフィールドのキーを指定。
'meta_value'(string)
カスタムフィールドの値を指定。
文字列として比較する。
'meta_value_num'(number)
カスタムフィールドの値を指定。
数値として比較する
'meta_compare'(string)
'meta_value'のテスト演算子。
使える値は以下。
データ型 意味 有効なデータ型
'=' 値と一致する すべて(省略時)
'!=' 値と一致しない すべて
'>' 値より大きい 数値系・日時系
'>=' 値以上 数値系・日時系
'<' 値より小さい 数値系・日時系
'<=' 値以下 数値系・日時系
'LIKE'

値で指定した文字列に一致する
(※SQLの「%○○%」と同じ)

'CHAR'
'NOT LIKE' 値で指定した文字列に一致しない CHAR
'IN' 値(配列)で指定した何れかに一致する すべて
'NOT IN' 値(配列)で指定した何れにも一致しない すべて
'BETWEEN' 2つの値で指定した範囲内(○以上○以下) 数値系・日時系
'NOT BETWEEN' 2つの値で指定した範囲外 数値系・日時系

keyやvalueを複数指定するパターン

パターン2。カスタムフィールドに関する指定をパラメータの配列で詳細に指定する方法について。

記述例

$args = array(
  'meta_query' => array(                  //カスタムフィールドに関するパラメーターをまとめた配列
    array(
      'key' => 'color',                   //カスタムフィールドのキーの指定
      'value' => array('red','blue'),     //カスタムフィールドの値の指定
      'type' => 'CHAR',                   //カスタムフィールドの値の型が何か教える
      'compare' => 'IN'                   //'value'パラメータの値に対する論理間関係を指定
    )
  )
);
'meta_query'(array)
カスタムフィールドパラメーター。この配列に情報を入れていく。
 'relation' ('AND' / 'OR')
meta_query の中に複数の配列を入れたときの論理値関係。使える値は 'AND' と 'OR' (デフォルトは'AND')。
※ひとつだけ配列を入れるときは使わない。
'key' (string)
カスタムフィールドのキー。
'value' (string / array)
カスタムフィールドの値。配列を指定できるのは compare が 'IN', 'NOT IN', 'BETWEEN' または 'NOT BETWEEN' の場合のみ。
WordPress 3.9 からは compare に 'EXISTS' または 'NOT EXISTS' を指定する場合は value を省略できるようになった。
'type' (string)
カスタムフィールドの値のタイプ。使える値は以下。
データ型 意味
'CHAR' 文字
'NUMERIC' SIGNEDの別名
'DECIMAL' 浮動小数点数
'SIGNED' 整数(符号あり)
'UNSIGNED' 整数(符号なし)
'DATE' 日付
'DATETIME' 日時
'TIME' 時刻
'BINARY' バイナリー
'compare' (string)
テスト演算子。使える値はパターン1の'meta_compare'と同じです。

この'meta_query'は、配列を入れ子にしてかなり複雑に扱うこともできるので、具体例を一つ紹介しておきます。

複数の条件を合わせて指定する場合の記述例

$args = array(
  'meta_query' => array(                  //カスタムフィールドに関するパラメーターをまとめた配列
    'relation' => 'AND',                  //AND : 条件1,2をどちらも満たすもの

    //条件1 ( 'color'というカスタムフィールドが 'red' もしくは 'blue' のもの )
    array(
      'key' => 'color',                   //カスタムフィールドのキーの指定
      'value' => array('red','blue'),     //カスタムフィールドの値の指定
      'type' => 'CHAR',                   //カスタムフィールドの値の型が何か教える
      'compare' => 'IN'                   //IN : 'value'パラメータで指定した値のいずれかに一致
    ),

    //条件2 ('price' の値が 1000 以下で、かつ、'size' が 'big' と一致するカスタムフィールドの値を持つもの)
    array(
        'relation' => 'AND',              //AND : 条件A,Bを両方満たすもの
        
        //条件2を形成する条件A (priceというカスタムフィールドの値が1000以下)
        array(
          'key' => 'price',
          'value' => 1000,
          'type' => 'NUMERIC',
          'compare' => '<'
        ),

        //条件2を形成する条件B (sizeをいうカスタムフィールドの値がbigと一致)
        array(
          'key' => 'size',
          'value' => 'big',
          'compare' => '='
        )
    )
  )
);

この例では、「colorがredもしくはblue」かつ、「priceが1000以下でsizeがbig」という条件に当てはまる投稿が取得できます。

その他 のパラメータ

日付をさらに詳細に指定

日付や日時に関するパラメータをを配列に入れてさらに詳細に指定する方法について。

'date_query'(array)
複雑な指定ができる日付パラメータ
array->( 'year' )(int)
月 (1 から 12)
array->( 'monthnum' )(int)
月 (1 から 12)
array( 'w' )(int)
週番号 (0 から 53)
array( 'day' )(int)
日 (1 から 31)
array( 'hour' )(int)
時 (0 から 23)
array( 'minute' )(int)
分 (0 から 60)
array( 'second' )(int)
秒 (0 から 60)
array( 'after' )(string / array)
この日付より後の投稿を取得。strtotime() 互換の文字列、または 'year', 'month', 'day' の値を持つ配列を指定可能
array( 'before' )(string / array)
この日付より前の投稿を取得。strtotime() 互換の文字列、または 'year', 'month', 'day' の値を持つ配列を指定可能
array( 'inclusive' )(bool)
after と before について、指定された日付ぴったりを含めるかどうか。
array( 'compare' )(string)
参考: WP_Date_Query::get_compare() を見てください。
array( 'colum' )(string)
クエリ対象とする(wp_posts テーブルの)カラム。デフォルトは 'post_date'。
array( 'relation' )('OR' / 'AND')
子の配列をどのように結合して比較するか。デフォルトは AND(かつ)。

投稿者の指定

ユーザーに関連付けられた投稿を指定する方法について。

'author'(int)
ユーザーID ( - で省く)
'author_name'(string)
ユーザ名( user_nicename )。性・名・ニックネームではない
'author__in'(array)
ユーザーIDで指定。複数を指定できる。
'author__not_in'(array)
ユーザーIDで指定。指定した投稿者を省く

パスワードの指定

バージョン 3.9 からパスワードの状態を指定できるようになっています。

'has_password'(bool)
パスワードで保護された投稿を表示するには true、保護されてない投稿を表示するには false を指定。パスワードの有無に関わらず表示したい場合は null (デフォルト) を指定。
'post_password'(string)
特定のパスワードで保護されている投稿を表示。

検索用の指定

検索機能に使われるパラメータを指定する

's'(string)
検索するキーワードを指定。search.phpなどで使用する。

権限の指定

ユーザーが適切な権限を持っていれば、公開済みの投稿と同様に、プライベートの記事を表示します。

'perm'('readable' / 'editable')
ユーザー権限を指定(readableまたはeditable)。

キャッシュの指定

取得したデータがキャッシュへ追加されるのを禁止できる。

'cache_results'(bool)
投稿情報のキャッシュをどうするか。falseで禁止
'update_post_meta_cache'(bool)
投稿のメタ情報(カスタムフィールドなど)のキャッシュをどうするか。falseで禁止
'update_post_term_cache'(bool)
投稿のターム情報(カテゴリなど)のキャッシュをどうするか。falseで禁止

戻り値の指定

戻り値を指定する。

'fields'(string)
どのフィールドを返すか指定。下の二つ以外の何かを指定するとすべてのフィールドを返す(デフォルト)。
'ids' 投稿IDの配列を返す
'id=>parent' プロパティに ID(投稿ID)と post_parent(親のID)を持つ stdClass オブジェクトの配列を返す

おまけ:具体例など

ループ内で使用する主要な情報

ループ内でよく使うであろう、記事タイトルや投稿日などはまとめて変数に入れて使用すると便利です。

//ループ上部で先に記述しておくと便利

$title    = esc_html(get_the_title()); //投稿タイトル
$url      = esc_url(get_permalink());  //投稿のurl
$date     = get_the_time('Y/m/d'); //投稿日
$modify    = get_the_modified_date('Y/m/d'); //更新日
$category = get_the_category();    //カテゴリ情報
$tags     = get_the_tags();        //タグ情報
$content  = mb_substr(esc_html(get_the_content()),0,60)."..."; //本文

//アイキャッチ画像のurlを取得しておく
if(has_post_thumbnail()):
  $src = get_thumb_src('サイズ');
else:
  $src = "デフォルト画像へのパス";
endif;

アイキャッチ画像の部分でのget_thumb_src()という関数は下の記事で紹介した関数です。

[WordPress] 投稿IDからアイキャッチ(サムネイル)画像のURLだけを取得する関数を作ってみた。サイズ指定ももちろん可能。[WordPress] 投稿IDからアイキャッチ(サムネイル)画像のURLだけを取得する関数を作ってみた。サイズ指定ももちろん可能。

ページャーを使用する時の記述例(WP_pagenaviを使用した場合)

//現在のページを教える
$paged = get_query_var('paged')? get_query_var('paged') : 1;
$args = array(

  //引数...

  'paged' => $paged,
);

$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
  while ($the_query->have_posts()) : $the_query->the_post();

    //ループ

  endwhile;
endif;
//wp_pagenaviの記述
 wp_pagenavi(array('query'=>$the_query));
 wp_reset_postdata();
- Thank you for reading. -

コメント

コメントする