WordPressループはWordPressを使いこなすために重要な知識の1つです。今回はWorePressループによる記事の出力についてまとめました。query_postsやWP_Queryを使うと色々な条件のもと記事を取得できるようになります。
WordPressループの基本的な利用
WordPressではURLによって、そのURLに対応する記事をデータベースから取得してます。このURLによって決定されるクエリのことを メインクエリ
と呼びます。
WordPressループは、メインクエリで取得した記事の数だけ繰り返されます。
固定ページや投稿ページのURLの場合、1件だけ記事が取得されます。なので、WordPressループの回数も1回だけです。カテゴリーページであればそのカテゴリーに対応する記事の数だけ、WordPressループが繰り返されます。
では、WordPressループの記述を見てみましょう。
if (have_posts()) :
while (have_posts()) : // 処理すべき記事があるか判定(WordPressの内部的カウンタをみている)
the_post(); // 処理すべき記事をセット(同時にWordPressの内部的カウンタを次に進める)
the_title(); // 記事のタイトルを出力
the_content(); // 記事の内容を出力
endwhile;
endif;
the_post()
によって記事がセットされて、 the_title()
などの記事に紐づく関数を利用できます。また、the_post()
を実行することで、 $post
という投稿情報を保持する変数も自動更新されます。
サブクエリの発行
トップページでは、
「上部に最新投稿記事を10件だけ表示」
「その下に○○カテゴリーの最新記事を5件だけ表示」
など、複数の条件で記事を取得して表示したいときがあります。
この場合は、WP_Query
を利用することでメインクエリとは別に サブクエリ
を生成し記事を取得することができます。
次の例では、サブクエリで最新投稿記事を10件取得しています。
// サブクエリをセット
$args = array(
'post_type' => 'post', // 投稿タイプ
// ・投稿 :post
// ・固定ページ :page
// ・カスタム投稿:カスタム投稿タイプ名
'posts_per_page' => 10, // 表示件数。 -1ならすべての投稿を取得
'orderby' => 'date', // ソート
// ・date :日付
// ・rand :ランダム
'order' => 'DESC')); // 降順(日付の場合、日付が新しい順)
}
$loop = new WP_Query($args);
// ループ
if (have_posts()) :
while (have_posts()) :
the_post();
/* 処理 */
endwhile;
endif;
// リセット(元の投稿データの復元)
wp_reset_postdata();
WP_Queryのパラメータ
WP_Queryのパラメータについては、関数リファレンス/WP Queryにて詳しい情報が書かれています。
下記にて、関数リファレンス/WP Queryに記述されている内容の一部を抜粋してます。詳しい情報は、リンク先にて確認することをお勧めします。
投稿者に関連付けられた投稿を表示
// ユーザー ID を用いて、ある投稿者の投稿を表示する場合:
$query = new WP_Query( 'author=123' );
// 'user_nicename' を用いて、ある投稿者の投稿を表示する場合:
$query = new WP_Query( 'author_name=rami' );
// 特定の複数の投稿者の投稿を表示する場合:
$query = new WP_Query( 'author=2,6,17,38' );
カテゴリーに関連付けられた投稿を表示
// カテゴリーIDを使用して、そのカテゴリー(さらにそのカテゴリーの子カテゴリー)に属する記事を表示:
$query = new WP_Query( 'cat=4' );
// カテゴリースラッグを使用して、そのカテゴリー(さらにそのカテゴリーの子カテゴリー)に属する記事を表示:
$query = new WP_Query( 'category_name=staff' );
// カテゴリー ID を使って、そのカテゴリー (子カテゴリーではない)に属する記事を表示:
$query = new WP_Query( 'category__in=4' );
// カテゴリー ID を使用して、それらのカテゴリーに属する記事を表示:
$query = new WP_Query( 'cat=2,6,17,38' );
// カテゴリースラッグを使用して、それらのカテゴリーに属する記事を表示:
$query = new WP_Query( 'category_name=staff,news' );
タグに関連付けられた投稿を表示
// タグのスラッグを使って、このタグを持つ記事を表示:
$query = new WP_Query( 'tag=cooking' );
// タグのIDを使って、このタグを持つ記事を表示:
$query = new WP_Query( 'tag_id=13' );
// これらのいずれかのタグを持つ記事を表示:
$query = new WP_Query( 'tag=bread,baking' );
// これらのすべてのタグを持つ記事を表示:
$query = new WP_Query( 'tag=bread+baking+recipe' );
// タグID 37 と 47 いずれかの記事を表示:
$query = new WP_Query( array( 'tag__in' => array( 37, 47 ) ) );
タクソノミーに関連付けられた投稿を表示
// カスタム分類 people の bob に関連付けられた投稿(post)を表示します :
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'people',
'field' => 'slug',
'terms' => 'bob',
),
),
);
$query = new WP_Query( $args );
// いくつかのカスタム分類から投稿を表示します:
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'movie_genre',
'field' => 'slug',
'terms' => array( 'action', 'comedy' ),
),
array(
'taxonomy' => 'actor',
'field' => 'term_id',
'terms' => array( 103, 115, 206 ),
'operator' => 'NOT IN',
),
),
);
$query = new WP_Query( $args );
// カテゴリー quotes に所属するか投稿フォーマットが quote の投稿(post)を表示します:
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'quotes' ),
),
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => array( 'post-format-quote' ),
),
),
);
$query = new WP_Query( $args );
キーワード検索によって投稿を表示
// 「キーワード」という検索語にマッチする投稿を表示します:
$query = new WP_Query( array( 's' => 'キーワード' ) );
投稿および固定ページに基づいてコンテンツを表示
// 投稿のIDを指定して表示する:
$query = new WP_Query( 'p=7' );
// 固定ページのIDを指定して表示する:
$query = new WP_Query( 'page_id=7' );
// 投稿のスラッグを指定して表示する:
$query = new WP_Query( 'name=about-my-life' );
// 固定ページのスラッグを指定して表示する:
$query = new WP_Query( 'pagename=contact' );
// 親ページの ID を使って子ページを表示する:
$query = new WP_Query( array( 'post_parent' => 93 ) );
// 子ページは除外し、トップレベルのページのみ表示する:
$query = new WP_Query( array( 'post_parent' => 0 ) );
// 配列中の ID で示されたページを親に持つ投稿を表示する:
$query = new WP_Query( array( 'post_parent__in' => array( 2, 5, 12, 14, 20 ) ) );
// 指定された投稿のみ表示:
$query = new WP_Query( array( 'post__in' => array( 2, 5, 12, 14, 20 ) ) );
// 指定された以外の全ての投稿を表示:
$query = new WP_Query( array( 'post__not_in' => array( 2, 5, 12, 14, 20 ) ) );
パスワード保護の有無に応じて表示
// パスワード保護された投稿のみ表示する:
$query = new WP_Query( array( 'has_password' => true ) );
// パスワード保護されていない投稿のみ表示する:
$query = new WP_Query( array( 'has_password' => false ) );
// パスワード保護の有無に関わらず投稿を表示する:
$query = new WP_Query( array( 'has_password' => null ) );
投稿タイプに関連付けられた投稿を表示
// 固定ページのみ表示:
$query = new WP_Query( array( 'post_type' => 'page' ) );
// 'any'(すべての)投稿タイプを表示(リビジョンと 'exclude_from_search' が TRUE になっている投稿タイプを除くすべての投稿タイプが含まれます):
$query = new WP_Query( array( 'post_type' => 'any' ) );
// カスタムポストタイプを含む複数のポストタイプを表示:
$args = array(
'post_type' => array( 'post', 'page', 'movie', 'book' )
);
$query = new WP_Query( $args );
投稿ステータスに関連付けられた投稿を表示
//下書きのみ表示:
$query = new WP_Query( array( 'post_status' => 'draft' ) );
//すべての添付ファイルを表示:
$args = array(
'post_status' => 'any',
'post_type' => 'attachment'
);
$query = new WP_Query( $args );
ページ送りパラメータ
// ページあたり3件の投稿を表示する:
$query = new WP_Query( array( 'posts_per_page' => 3 ) );
// 1つのページに全ての投稿を表示する:
$query = new WP_Query( array( 'posts_per_page' => -1 ) );
// ページネーションを無効にして全ての投稿を表示する:
$query = new WP_Query( array( 'nopaging' => true ) );
// 現在のページから投稿を表示する:
$query = new WP_Query( array( 'paged' => get_query_var( 'paged' ) ) );
投稿の並びを指定
// 投稿をその 'title' で降順に並べ替えて表示します:
$args = array(
'orderby' => 'title',
'order' => 'DESC',
);
$query = new WP_Query( $args );
// 投稿を 'menu_order' の降順でソートして表示します。同じ値なら投稿の 'title' の順にします:
$args = array(
'orderby' => 'menu_order title',
'order' => 'DESC',
);
$query = new WP_Query( $args );
//ランダムに投稿を1件表示する:
$args = array(
'orderby' => 'rand',
'posts_per_page' => '1',
);
$query = new WP_Query( $args );
// 投稿をコメント数の順に表示する:
$args = array(
'orderby' => 'comment_count'
);
$query = new WP_Query( $args );
// 'Product' 投稿タイプをカスタムフィールド 'Price' で並び替えて表示:
$args = array(
'post_type' => 'product',
'orderby' => 'meta_value_num',
'meta_key' => 'price',
);
$query = new WP_Query( $args );
// 別々の表示順(昇順/降順)の 'title' と 'menu_order' で並べ替えた固定ページを表示(バージョン 4.0 から利用可能):
$args = array(
'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' )
);
$query = new WP_Query( $args );
// カスタムフィールドとカスタム投稿タイプを 'orderby' に指定
// 投稿タイプが 'my_custom_post_type' で 'age' 順、そして 'age' が3か4のものだけを表示(meta_query を使用)。
$args = array(
'post_type' => 'my_custom_post_type',
'meta_key' => 'age',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'age',
'value' => array( 3, 4 ),
'compare' => 'IN',
),
),
);
$query = new WP_Query( $args );
期間に関連付けられた投稿を表示
// 2012年12月12日の投稿を返す:
$query = new WP_Query( 'year=2012&monthnum=12&day=12' );
// または:
$args = array(
'date_query' => array(
array(
'year' => 2012,
'month' => 12,
'day' => 12,
),
),
);
$query = new WP_Query( $args );
// 今日の投稿を返す:
$today = getdate();
$query = new WP_Query( 'year=' . $today['year'] . '&monthnum=' . $today['mon'] . '&day=' . $today['mday'] );
// または:
$today = getdate();
$args = array(
'date_query' => array(
array(
'year' => $today['year'],
'month' => $today['mon'],
'day' => $today['mday'],
),
),
);
$query = new WP_Query( $args );
// 今週の投稿を返す:
$week = date( 'W' );
$year = date( 'Y' );
$query = new WP_Query( 'year=' . $year . '&w=' . $week );
// または:
$args = array(
'date_query' => array(
array(
'year' => date( 'Y' ),
'week' => date( 'W' ),
),
),
);
$query = new WP_Query( $args );
// 平日の午前9時から午後5時までの投稿を返す
$args = array(
'date_query' => array(
array(
'hour' => 9,
'compare' => '>=',
),
array(
'hour' => 17,
'compare' => '<=',
),
array(
'dayofweek' => array( 2, 6 ),
'compare' => 'BETWEEN',
),
),
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
// 1月1日から2月28日までの投稿を返す
$args = array(
'date_query' => array(
array(
'after' => 'January 1st, 2013',
'before' => array(
'year' => 2013,
'month' => 2,
'day' => 28,
),
'inclusive' => true,
),
),
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
// 1年より前の投稿で1ヶ月以内に変更されたものを返す
$args = array(
'date_query' => array(
array(
'column' => 'post_date_gmt',
'before' => '1 year ago',
),
array(
'column' => 'post_modified_gmt',
'after' => '1 month ago',
),
),
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
カスタムフィールドに関連付けられた投稿を表示
// カスタムフィールドの値に関係なく、カスタムフィールドのキーが 'color' の投稿を表示します:
$query = new WP_Query( array( 'meta_key' => 'color' ) );
// カスタムフィールドのキーに関係なく、カスタムフィールドの値が 'blue' の投稿を表示します:
$query = new WP_Query( array( 'meta_value' => 'blue' ) );
// カスタムフィールドのキーに関係なく、カスタムフィールドの値が 'blue' の固定ページを表示します:
$args = array(
'meta_value' => 'blue',
'post_type' => 'page'
);
$query = new WP_Query( $args );
// カスタムフィールドのキーが 'color'、値が 'blue' の投稿を表示します:
$args = array(
'meta_key' => 'color',
'meta_value' => 'blue'
);
$query = new WP_Query( $args );
// カスタムフィールドのキーが 'color'、値が 'blue' ではない投稿を表示します:
$args = array(
'meta_key' => 'color',
'meta_value' => 'blue',
'meta_compare' => '!='
);
$query = new WP_Query( $args );
// イベントの投稿('event' カスタム投稿タイプ)を表示します。開催日のカスタムフィールドのキーが 'event_date'、値が今日以降とします。
$args = array(
'post_type' => 'event',
'meta_key' => 'event_date',
'meta_value' => date( "Ymd" ), // 'event_date' の保存形式に合わせる
'meta_compare' => '>',
);
$query = new WP_Query( $args );
// 製品('product' カスタム投稿タイプ)のうち、値段('price' カスタムフィールド)が 22 以下 であるものを表示します。
// 値を指定するのに 'meta_value' パラメータを使うと 99 が 100 より大きいと判定されます(数値ではなく文字列として保存されているため)。
$args = array(
'meta_key' => 'price',
'meta_value_num' => '22',
'meta_compare' => '<=',
'post_type' => 'product'
);
$query = new WP_Query( $args );
// カスタムフィールドのキーに関係なく、値がゼロ (0) のカスタムフィールドを持つ投稿を表示します:
$args = array(
'meta_value' => '_wp_zero_value'
);
$query = new WP_Query( $args );
// 1つのカスタムフィールドからの記事を表示します:
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE'
)
)
);
$query = new WP_Query( $args );
// 製品(カスタム投稿タイプ 'product')について、
// 色(カスタムフィールドのキー 'color')が青('blue')ではなく('NOTE LIKE')、
// 値段(キー 'price'、タイプ 'numeric')が20と100の間にある('BETWEEN')ものを表示します。
// 'relation' を省略しているので 'AND' になることに注意してください:
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE',
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN',
),
),
);
$query = new WP_Query( $args );
// 製品について、色が青ではないか、または値段が20と100の間にあるものを表示します。
// ひとつ前の例と違って 'relation' を指定しています:
$args = array(
'post_type' => 'product',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE',
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN',
),
),
);
$query = new WP_Query( $args );
ユーザーが適切な権限を持つ場合に投稿を表示
// ユーザーが適切な権限を持つ場合に、公開済みと非公開の投稿を表示します:
$args = array(
'post_status' => array( 'publish', 'private' ),
'perm' => 'readable',
);
$query = new WP_Query( $args );
メインクエリの改変
プラグインでページ送りを実装していると、WP_Queryの利用時にページ送りが動作しなくなることがあります。
これはメインクエリの情報をもとにページ送りが実装されているためです。
この場合は、メインクエリを改変することでページ送りが実装されたまま、別条件による記事の取得が可能となります。
メインクエリを改変するには、query_posts()
を利用します。
// メインクエリの改変
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => get_query_var('page'), // ページ数
// get_query_var('page')で現在のページ番号を取得
'orderby' => 'date',
'order' => 'DESC'));
}
query_posts( $args );
// ループ
if (have_posts()) :
while (have_posts()) :
the_post();
/* 処理 */
endwhile;
endif;
/* ページ送りの処理 */
// リセット
wp_reset_query();
query_posts()
は非推奨なようです。今のところページ送りを実装したいときだけ利用してますが、今後不具合がでるかもしれません。