WordPressで投稿一覧を作成する時に使うのは get_posts? WP_Query? 違いと使い方解説【WordPress自作テーマ小ネタ】

WordPressサイトのテーマ自作やカスタマイズで、
トップページなどに最新のお知らせを読み込みたい
ということは多々あるかと思います。

その際、よく使われるのが 下記の2つの関数です。

そこで今回は、この2つの関数を使って、トップページなど任意のページに指定の記事読み込みの作り方、それぞれの違いなどを解説いたします。

WordPressテーマの自作方法について詳しく知りたい方はこちら

はじめに:カテゴリ以外で一覧が出ない理由

WordPressでは、テンプレートのファイル名によって、表示されるページにあったテンプレートを呼び出しされるようになっています。

通常、カテゴリページなど、投稿記事の一覧が表示されるページは、「アーカイブインデックスページ」と呼ばれ、
archive.php や category.php といった名称のテンプレートを用いて表示しています。

自作テーマ作りやカスタマイズを始めたばかりの方は、すでに一覧が表示されているcategory.phpなどの記述をとりあえずコピペしてみたけど、出ない!という方もいらっしゃるかもしれません。

アーカイブ用テンプレートの記述をトップページ用などのテンプレートにコピペしても一覧は表示されません。

出ない理由を、すごくざっくりと言いますと

アーカイブページ
ページを表示する前に 一覧表示するためのデータを裏側に持っている
トップページなど他のページ
ページを表示する前に 一覧表示するためのデータを裏側に持っていない

という、「どんなページを表示しますよ」とテンプレートに表示させるデータが異なってます。

そのため、アーカイブページ以外で記事一覧を表示したい場合は、表示したいページで一覧表示するためのデータを取得する必要があります。

記事一覧情報の取得方法

じゃあ、どうやってその一覧情報を取得するの?というところで、冒頭の「get_posts」や「WP_Query」などの任意のカスタムループを作成できる関数を使用して表示したいカテゴリなどの記事一覧情報を取得します。

get_posts の使い方

指定した数分、指定したカテゴリなどの記事情報を取得し、取得情報がある限りループさせることで、一覧を作成します。

<?php
// 取得したい内容を配列に記載します(不要箇所は省略可)
$args = array(
	'posts_per_page'   => 5, // 読み込みしたい記事数(全件取得時は-1)
	'category'         => 1, // 読み込みしたいカテゴリID(複数の場合は '1,2')
	'orderby'          => 'ID', // 何順で記事を読み込むか(省略時は日付順)
	'order'            => 'DESC', // 昇順(ASC)か降順か(DESC)
	'exclude'          => '111, 125', // 一覧に表示したくない記事のID(複数時は,区切)
);

// 配列で指定した内容で、記事情報を取得
$datas = get_posts( $args );

// 取得した記事情報の表示
if ( $datas ): // 記事情報がある場合はforeachで記事情報を表示

// ↓ ループ開始 ↓
foreach ( $datas as $post ): // $datas as $post の $datas は取得時に設定した変数名、$postは変更不可
	setup_postdata( $post ); // アーカイブページ同様にthe_titleなどで記事情報を表示できるようにする
?>

	〜 ループ内で表示させたい記述を書く 〜

<?php
endforeach; 
// ↑ ループ終了 ↑

else: // 記事情報がなかったら
?>

	〜 記事がない場合の記述 〜

<?php
endif;

// 一覧情報取得に利用したループをリセットする
wp_reset_postdata();
?>

$args に指定できる項目は、「WordPress Codex 日本語版」などを合わせてご確認ください。

WP_Queryの使い方

指定した数分、指定したカテゴリなどの記事情報を取得し、取得情報がある限りループさせることで、一覧を作成します。

<?php
// 取得したい内容を配列に記載します(不要箇所は省略可)
$args = array(
	'posts_per_page'   => 5, // 読み込みしたい記事数(全件取得時は-1)
	'category'         => 1, // 読み込みしたいカテゴリID(複数の場合は '1,2')
	'orderby'          => 'ID', // 何順で記事を読み込むか(省略時は日付順)
	'order'            => 'DESC', // 昇順(ASC)か降順か(DESC)
	'exclude'          => '111, 125', // 一覧に表示したくない記事のID(複数時は,区切)
);

// 配列で指定した内容で、記事情報を取得
$the_query = new WP_Query( $args );

// 取得した記事情報の表示
if ( $the_query->have_posts() ): // 記事情報がある場合はforeachで記事情報を表示

// ↓ ループ開始 ↓
while ( $the_query->have_posts() ):
	$the_query->the_post(); // アーカイブページ同様にthe_titleなどで記事情報を表示できるようにする
?>

	〜 ループ内で表示させたい記述を書く 〜

<?php
endwhile; 
// ↑ ループ終了 ↑

else: // 記事情報がなかったら
?>

	〜 記事がない場合の記述 〜

<?php
endif;

// 一覧情報取得に利用したループをリセットする
wp_reset_postdata();
?>

get_postsとWP_Queryの違い

get_postsもWP_Queryも、ちょっと書き方が違うだけで同じじゃない?
と思われるかと思いますが、持っているデータの量が異なります。

違いは、 get_posts がどんな値を取得してくるか、Wordpress側が用意している内容を確認するとわかります。

下記は、wp-includes/post.php 内の get_posts について記載された箇所です。

function get_posts( $args = null ) {
	$defaults = array(
		'numberposts'      => 5,
		'category'         => 0,
		'orderby'          => 'date',
		'order'            => 'DESC',
		'include'          => array(),
		'exclude'          => array(),
		'meta_key'         => '',
		'meta_value'       => '',
		'post_type'        => 'post',
		'suppress_filters' => true,
	);

	$parsed_args = wp_parse_args( $args, $defaults );
	if ( empty( $parsed_args['post_status'] ) ) {
		$parsed_args['post_status'] = ( 'attachment' === $parsed_args['post_type'] ) ? 'inherit' : 'publish';
	}
	if ( ! empty( $parsed_args['numberposts'] ) && empty( $parsed_args['posts_per_page'] ) ) {
		$parsed_args['posts_per_page'] = $parsed_args['numberposts'];
	}
	if ( ! empty( $parsed_args['category'] ) ) {
		$parsed_args['cat'] = $parsed_args['category'];
	}
	if ( ! empty( $parsed_args['include'] ) ) {
		$incposts                      = wp_parse_id_list( $parsed_args['include'] );
		$parsed_args['posts_per_page'] = count( $incposts );  // Only the number of posts included.
		$parsed_args['post__in']       = $incposts;
	} elseif ( ! empty( $parsed_args['exclude'] ) ) {
		$parsed_args['post__not_in'] = wp_parse_id_list( $parsed_args['exclude'] );
	}

	$parsed_args['ignore_sticky_posts'] = true;
	$parsed_args['no_found_rows']       = true;

	$get_posts = new WP_Query;
	return $get_posts->query( $parsed_args );

}

最後らへんの行に注目

$get_posts = new WP_Query;
return $get_posts->query( $parsed_args );

ここを見ると、get_posts は WP_Queryの一部の情報だけを持っている ということになります。

get_posts と WP_Queryの使い分け

例えば、トップページにお知らせカテゴリの最新5件を表示したい!という場合は、どちらを利用しても構いません。
個人的には余分な情報を持っていない分、get_postsを利用することが多いです。

ですが、

投稿編集ページのサイドナビ「ステータスと公開状態」にある、ブログのトップに固定 を利用したい場合、WP_Queryで記述する必要があります。
また、ページネーションをつけたいという場合、functions.phpに記述する方法もありますが、直接テンプレートに書きたいという場合もWP_Queryで記述します。

自分が表示したい内容や用途に合わせて、使い分ける形となります。

お問い合わせ

ガリレオ アンド ヴィーナス合同会社では、Wordpressを使用したコーポレートサイトなどの構築の他、カート機能のついたECショップなどのWEBサイト制作を行っております。

また、ご自身でサイト作成をされたい方向けにセミナー等も開催しております。

詳しくはお気軽にお問い合わせください。

    関連記事

    1. WordPressを管理するアプリ「WordPressサイトビルダー」…

    2. WordPress セミナーのご案内 1月27日

    3. WordPressサイトの閲覧をパスワードで保護する方法2選!プラグイ…

    4. ブログなどの投稿記事で実際にWEBデザイナーがよく使用する CSS一覧…

    5. Advanced Custom Fieldsの基本的な使い方!入力欄を…

    6. まだClassic editor使っている方へ WordPressのブ…