WordPressの get_posts により、 デベロッパーWordPressデータベースからコンテンツの一部を取得できます。これは強力な機能です。探し出す投稿、ページ、カスタム投稿タイプを詳細に指定し、好みの結果を取得してから、アイテムをフィルタリング、順序付けできます。PHP / MySQLのプロさながらの操作ができるということです。

ただ、PHPに詳しくない方でも心配いりません。見たりまたは読んだりできるPHPチュートリアルはたくさんありますので、簡単に勉強できます。get_posts 関数はパラメータの配列を保持し、単純または高度なクエリを作成できるようにするため、PHPの知識が少しあれば、ウェブサイトに表示する投稿のカスタムリストを作成することができます。

WordPressの get_posts を利用することは、2つのステップから構成されます。

  • まず、カスタムクエリを作成する必要があります。実際、MySQLクエリのような見た目ではなく、SELECTステートメントを記述することもありません。パラメータの配列を定義して、それをget_posts 関数に渡すだけです。WordPressがその配列を実際のセキュアなMySQLクエリに変換し、データベースに対して実行し、投稿の配列を返します。
  • 次に、foreachサイクルでget_posts によって返される結果を走査する必要があります。

それでは、この投稿では、まず上記の重要な概念、特にget_posts の仕組み、カスタムクエリの作成方法、フロントサイトでのデータの表示方法について説明します。

そして次に、テストと開発のためにステージング環境で実際に編集、使用できるコードのスニペットを用いて実際の例をご紹介します。

注意:通常、「投稿」、「ページ」、「カスタム投稿タイプ」は区別されるものですが、この記事では、通常のブログの投稿だけでなく、ページやカスタム投稿タイプも含めて「投稿」という用語を使用します。これらの投稿タイプはすべて、データベースの「wp_posts」テーブルに保存されます。投稿タイプの主な違いは、 「post_type」フィールドの値です。開発者の観点から見ると、投稿、ページ、カスタム投稿タイプはすべて「投稿」となります。

WordPress get_posts 関数の紹介

Codexは、get_posts 関数を以下のように説明しています。

最新の投稿、または特定の条件に一致する投稿の配列を取得する。

get_posts を以下のように使うことができます。

$args = array(
	'numberposts'	=> 20,
	'category'		=> 4
);
$my_posts = get_posts( $args );

if( ! empty( $my_posts ) ){
	$output = '<ul>';
	foreach ( $my_posts as $p ){
		$output .= '<li><a href="' . get_permalink( $p->ID ) . '">' 
		. $p->post_title . '</a></li>';
	}
	$output .= '<ul>';
}

上記の関数は、指定されたカテゴリ(デフォルトでは post_typepost です)の最新の20件のブログ投稿を取得し、$post オブジェクトの配列を返します。配列を反復処理して、画面に投稿を表示できます。とても簡単ですよね?

get_postsWP_Queryを使用して投稿アイテムを取得し、 WP_Query で使用可能な同じパラメータの配列を保持します(例外はほとんどありません)。したがって、カスタムクエリの作成に使用できる変数は膨大にあります。パラメータは、次の15のカテゴリにグループ分けされています。

  • 投稿者パラメータ
  • カテゴリパラメータ
  • タグパラメータ
  • タクソノミーパラメータ
  • 検索パラメータ
  • 投稿&ページパラメータ
  • パスワードパラメータ
  • 投稿タイプパラメータ
  • 順序づけパラメータ
  • 日付パラメータ
  • カスタムフィールド(投稿メタデータ)パラメータ
  • 権限パラメータ
  • MIMEタイプパラメータ
  • キャッシュパラメータ
  • リターンフィールドパラメータ

上記のリストをざっと見てみると、WordPressデータベースに対して作成・実行できるさまざまなカスタムクエリがあることがわかります。それでは、クエリパラメータをさらに深く掘り下げて、投稿リストの作成を始めましょう。

WordPress get_posts でクエリを作成する方法

パラメータの各カテゴリは、同じ情報に関連しています。たとえば、IDまたはニックネームで投稿者を定義し、指定した投稿者からの投稿を取得/除外するクエリを作成することができます。同様に、カテゴリ、タグ、タクソノミー、日付、カスタムフィールドなどから投稿を取得するクエリも作成できます。

パラメータを使用して単純なクエリを作成する方法

多くのパラメータは、それが属するカテゴリに関係なく、非常によく似た方法で使用できます。たとえば、次のパラメータを使用すると、投稿者に基づきデータベースを照会できます。

  • author (整数) – 投稿者ID
  • author_name (文字列) – 投稿者の user_nicename
  • author__in (配列) – 複数の投稿者IDの配列
  • author__not_in (配列) – 排除されるべき複数の投稿者IDの配列

これらのパラメータをどのように使えばいいのでしょうか?

次の例では、パラメータ author は、IDが「1」である投稿者によって作成された最新のブログ投稿が必要であることを指定しています。

$my_posts = get_posts( array( 'author' => 1 ) );

「author」パラメータを他の方法で、データベースのクエリ作成に使うこともできます。

// return an array of posts from specific authors
$my_posts = get_posts( array( 'author' => '1,5,12' ) );
// return an array of posts excluding the specified author
$my_posts = get_posts( array( 'author' => -1 ) );

このように、パラメータの値に応じて、単一の投稿者(整数)、複数の投稿者(コンマ区切りの値のリスト)からの投稿、または特定の著者を除外した(負の値)結果が得られます。

他のパラメータで、柔軟性を高めることもできます。たとえば、次の get_posts は、複数の投稿者からの最新のブログ投稿の配列を返します。

// return an array of posts from multiple authors
$my_posts = get_posts( array( 'author__in' => array( 1, 5, 12 ) ) );

そして、複数の投稿者を除外することもできます。

// return an array of posts from multiple authors
$my_posts = get_posts( array( 'author__not_in' => array( 1, 5, 12 ) ) );

同様に、カテゴリパラメータ、タグパラメータ、投稿タイプパラメータを使用できますが、特定の違いがあります。例として、カテゴリパラメータを見てみましょう。

  • cat (int)
  • category_name (string)
  • category__and (array)
  • category__in (array)
  • category__not_in (array)

とにかく、すべてのパラメータがこれらのパラメータほど使いやすいわけではありません。さらに、カテゴリパラメータ、投稿タイプパラメータ、MIMEタイプパラメータなどをすべて単一のクエリで使用できます。これにより、結果として受け取るデータの中身をきめ細かく制御でき、投稿タイプ、カスタムタクソノミー、カスタムフィールド全体に基づいて、より高度なクエリを構築できます。

それでは、もう少し先に進みましょう!

WordPressで高度なクエリを作成する方法

カスタム投稿タイプとカスタムタクソノミーに基づくより高度なクエリを使用して、一歩前進しましょう。次の投稿タイプがあるとします。

名前: book
タクソノミー名: book_category、book_author
対応する項目: title、 editor、 thumbnail、 excerpt、 custom-fields

カスタム投稿タイプとカスタムタクソノミー

book_category カスタムタクソノミーの最新の書籍のリストが欲しいとします。引数の配列は次のとおりです。

$args = array(
	'post_type'		=> 'book',
	'tax_query'		=> array(
		array(
			'taxonomy'	=> 'book_category',
			'field'		=> 'slug',
			'terms'		=> 'sci-fi'
		)
	),
);

上記の引数は、sci-fi book_category にあるすべての本を取得するようにWordPressに指示します。

tax_query パラメータは、引数配列の配列(つまり配列の配列)を取ります。このようにネスト構造にある配列により、以下の例に示すように、複数のタクソノミーに基づいて非常に複雑なクエリが作成できます。

$args = array(
	'numberposts'	=> 10,
	'post_type'		=> 'book',
	'relation'		=> 'AND',
	'tax_query'		=> array(
		array(
			'taxonomy'	=> 'book_category',
			'field'		=> 'slug',
			'terms'		=> 'sci-fi'
		),
		array(
			'taxonomy'	=> 'book_author',
			'field'		=> 'term_id',
			'terms'		=> 22
		)
	)
);

これらのパラメータにより、IDが#22の book_author が作成した sci-fi book_category の最新の10の book 投稿タイプのリストを取得できます。relation パラメータが、 tax_query にリストされているタクソノミーそれぞれの間の論理的な関係を定義します。上記では、sci-fi カテゴリに属する、かつ、著者#22によって作成されたすべての書籍を取得する必要があるので、値を AND に設定しました。

カスタムフィールドパラメータを使用してメタクエリを作成する方法

時に、特定のカスタムフィールドキーや値に基づいて投稿のリストを作成することもあるでしょう。

$args = array(
	'meta_key'		=> 'cover',
	'meta_value'	=> 'paperback',
	'meta_compare'	=> '='
);

これらのパラメータを使用すると、カスタムフィールドキーと値からすべての投稿を取得できます。 meta_compare は、 meta_value パラメータの値をテストするために必要な演算子を設定します。ここでは、meta_value はデフォルト値でもある = です。

利用可能な値は=!=>>=<<=LIKENOT LIKEINNOT INBETWEENNOT BETWEENNOT EXISTSREGEXPNOT REGEXPまたはRLIKEです。

これは非常に簡単な例ですが、より高度なクエリも作成できます。次の例では、2010年以降に発行されたファンタジーの本についてデータベースにクエリを実行します。

$args = array(
	'post_type'		=> 'book',
	'meta_key'		=> 'year_published',
	'meta_value_num'	=> 2010,
	'meta_compare'	=> '>',
	'tax_query'		=> array(
		array(
			'taxonomy'	=> 'book_category',
			'field'		=> 'slug'
			'terms'		=> 'fantasy'
		)
	)
);

そして、さらに先へ進むこともできます。次の例では、カスタムタクソノミーを持つ投稿タイプと、2つのカスタムフィールドを混在させています。

$args = array(
	'post_type'		=> 'book',
	'tax_query'		=> array(
		array(
			'taxonomy'	=> 'book_category',
			'field'		=> 'slug'
			'terms'		=> array( 'fantasy' )
		)
	),
	'meta_query'	=> array(
		'relation'		=> 'AND',
		array(
			'key'		=> 'year_published',
			'value'		=> 2010,
			'type'		=> 'numeric',
			'compare'	=> '>',
		),
		array(
			'key'		=> 'price',
			'value'		=> array( 10, 25 ),
			'type'		=> 'numeric',
			'compare'	=> 'BETWEEN',
		)
	)
);

ここでは、一連のパラメータで、2010年以降に発行されたファンタジー本のリストを取得しています。本の価格は10ドルから25ドル(BETWEEN)です。

meta_query パラメータが tax_query パラメータとよく似ていることがわかります。配列のまとまりを構成するため、複数のメタキー/値のペアに基づいて高度なクエリが作成できます。クエリパラメータの包括的なリストと多数の例については、 WP_Queryのドキュメンテーションをご覧ください。

get_postsが5つのWordPressの投稿に限定されている理由とは?

get_posts 関数は WP_Query::parse_query()と同じ引数を取りますが(Codexを参照)、いくつかの特定のパラメータは WP_Query オブジェクトとは少し異なる動作をします。

クエリで numberposts パラメータを使用していないはずなのに、リストに5つのアイテムしか表示されない…一体、なぜ、そんなことが起こるのでしょうか?

デフォルトでは、「設定」→「表示設定」の管理ページで設定した投稿の数によって、WordPressクエリによって取得される投稿の数が決まります。とにかく、 numberpostsposts_per_page にカスタム値を指定しない場合、 get_posts は異なる数の投稿を返します。

  • numberpostsは取得する投稿の総数です。これはWP_Queryposts_per_pageのエイリアスですが、2つには違いがあります。デフォルトでは、get_posts の使用時に取得する投稿の数は5ですが、 WP_Queryposts_per_page におけるデフォルトはあなたのWordPressサイトのページ毎の投稿数になります。引数の配列で numberposts または posts_per_page のカスタム値を設定することにより、デフォルト値をオーバーライドできます。

numberposts に加えて、以下のパラメータは get_posts に固有のものです。

  • categoryはコンマで区切ったカテゴリIDのリストです。WP_Querycatパラメータのエイリアスです。
  • includeはコンマで区切った投稿IDのリストです。WP_Querypost__inパラメータのエイリアスです。
  • excludeはコンマで区切った投稿IDのリストです。
  • suppress_filtersはフィルタリングを無効にするかどうかを決めます。このパラメータのデフォルトは get_postsではtrueで、WP_Query ではfalseとなっています(Trackを参照)。

関数は、 wp-includes/post.php で定義されます。 Track (WordPress 5.2) またはローカルのWordPressインストールファイルのソースコードから、 get_posts の仕組みを深く掘り下げることができます。

アイテムの順序づけ

orderby や order は結果として獲得したアイテムの順序づけを行います。ID、 author、 title、 name、 type、 date、 modified、 parent、 rand、 comment_count その他たくさんの方法で、昇順/降順を設定しながら、並べ替えができます。

簡単なクエリがある場合は、orderや  orderby の値を設定するだけでOKです。次の例では、投稿は投稿名の昇順で並べ替えられています。

$args = array(
	'author'	=> '1,5,12',
	'orderby'	=> 'name',
	'order'		=> 'ASC'
);

非常にシンプルです。では、複雑なクエリがある場合はどうでしょうか?つまり、高度なメタクエリで、1つや複数のカスタムフィールド値でアイテムを並べ替えることはできるのでしょうか?

WordPress 4.0、WordPress 4.2は、orderby と  meta_query パラメータに重要な改善をもたらしました。メタクエリの特定の節による順序付けが可能になる新しい構文が用意されたのです。この新しい構文のおかげで、インデックスを使用して、 orderby パラメータからメタクエリの特定の節へ参照することができます。

このような改善により、上記の例のメタクエリは次のように記述できます。

$args = array(
	'meta_query'	=> array(
		'relation'		=> 'AND',
		'year_clause' => array(
			'key'		=> 'year_published',
			'value'		=> 2010,
			'type'		=> 'numeric',
			'compare'	=> '>',
		),
		'price_clause' => array(
			'key'		=> 'price',
			'value'		=> array( 10, 25 ),
			'type'		=> 'numeric',
			'compare'	=> 'BETWEEN',
		)
	),
	'orderby' => 'price_clause',
);

上記の例では、price_clause で要素を順序付けしました。

さらに多くのことができます。WordPress 4.0では、次の例に示すように、単一のインデックスではなく、メタクエリインデックスの配列を get_posts に渡すことができます。

$args = array(
	'meta_query'	=> array(
		'relation'		=> 'AND',
		'year_clause' => array(
			'key'		=> 'year_published',
			'value'		=> 2010,
			'type'		=> 'numeric',
			'compare'	=> '>',
		),
		'price_clause' => array(
			'key'		=> 'price',
			'value'		=> array( 10, 25 ),
			'type'		=> 'numeric',
			'compare'	=> 'BETWEEN',
		)
	),
	'orderby' => array( 'price_clause' => 'ASC', 'year_clause' => 'DESC' ),
);

高度なメタクエリを作成し、最初に price_clause で昇順、次に year_clause で降順で結果を並べ替えました。

Codexから並べ替えオプションの全リストが確認できます。

次はフロントページにデータを表示しましょう。

おすすめの記事: phpinfoページを簡単に作成、使用する方法

get_postsで返されたデータを表示する方法

WordPressの get_postsWP_Post オブジェクトを返し、 wp_posts データベーステーブルに保存されている選択された各投稿の変数が利用できるようになります。

  • ID
  • post_author
  • post_name
  • post_type
  • post_title
  • post_date
  • post_date_gmt
  • post_content
  • post_excerpt
  • post_status
  • comment_status
  • ping_status
  • post_password
  • post_parent
  • post_modified
  • post_modified_gmt
  • comment_count
  • menu_order
phpMyAdminのwp_postsテーブルの構造
phpMyAdminのwp_postsテーブルの構造

次のような foreach サイクルでこれらのデータに簡単にアクセスできます。

$custom_posts = get_posts( $args );

if( ! empty( $custom_posts ) ){
	$output = '<ul>';
	foreach ( $custom_posts as $p ){

		$output .= '<li><a href="' 
		. get_permalink( $p->ID ) . '">' 
		. $p->post_title . '</a></li>';
	}

	$output .= '</ul>';
}

return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';

get_posts が少なくとも1つの投稿を見つけると、一連のアイテムが返され、それを走査して、投稿のタイトルと元の投稿へのリンクを表示できるようになります。対応する WP_Post 変数がないため、 get_permalink 関数を使用して投稿のパーマリンクを取得しました。

ここまでは非常にシンプルですが、WordPress get_posts を使用してそのコードを実装し、投稿のカスタムリストを作成するにはどうすればよいのでしょうか?

ページに投稿のリストを表示するには、いくつかの方法が考えられます。

実践編:ショートコードでアイテムのカスタムリストを表示する方法

コンテンツに組み込むことのできる、素早く簡単なショートコード作成方法をご紹介します。以前の記事で既にショートコード自体を扱っているので、これについては、ここでは深く掘り下げません。

まず、 ローカルWordPressインストールwp-content/pluginsフォルダまたはステージング環境に新しいディレクトリを作成します。この例では、ディレクトリをkinsta-shortcodesと名付けました。

wp-content/plugins/kinsta-shortcodes/ に新規ディレクトリと同じ名前の.phpファイル kinsta-shortcodes.php を作成します。

お使いの任意のテキストエディタで新しいファイルを開き、次の内容を一番上に記述します。

<?php
/**
 * @package Kinsta_shortcodes
 * @version 1.0
 */
/*
Plugin Name: Kinsta shortcodes
Plugin URI: http://wordpress.org/extend/plugins/#
Description: This is an example plugin 
Author: Your Name
Version: 1.0
Author URI: https://yourwebsite.com/
*/

新しいプラグインができましたが、まだ何の機能もありません。 WordPressダッシュボードの「プラグイン」管理画面に移動し、新しいプラグインを有効化( wp-config.phpWP_DEBUGtrue に設定されていることを確認)します。

これで、サンドボックスにコードを記述する準備が整いました。次の手順は、カスタムショートコードのフックを登録することです。

/**
 * Add a hook for a shortcode tag
 */
function kinsta_shortcodes_init(){
	add_shortcode( 'kinsta_get_posts', 'kinsta_get_posts_cb' );
}
add_action('init', 'kinsta_shortcodes_init');

kinsta_get_posts がショートコード名で、 kinsta_get_posts_cb は以下で定義されるコールバックです。

/**
 * Register a shortcode
 *
 * @param array $atts Array of shortcode attributes
 */
function kinsta_get_posts_cb( $atts ){

	// safely extract custom arguments and set default values
	extract( shortcode_atts(
			array(
				'numberposts'		=> 3,
				'post_type'			=> 'post',
				'book_category'		=> 'fantasy',
				'year_published'	=> 1900,
				'price_min'			=> 0,
				'price_max'			=> 50
			),
			$atts,
			'kinsta_get_posts'
		) );

	// define the array of query arguments
	$args = array(
		'numberposts'	=> $numberposts,
		'post_type'		=> $post_type,
		'tax_query'		=> array(
			array(
				'taxonomy'	=> 'book_category',
				'field'		=> 'slug',
				'terms'		=> $book_category,
			)
		),
		'meta_query'	=> array(
			'relation'		=> 'AND',
			'year_clause'	=> array(
				'key'		=> 'year_published',
				'value'		=> $year_published,
				'type'		=> 'numeric',
				'compare'	=> '>',
			),
			'price_clause'	=> array(
				'key'		=> 'price',
				'value'		=> array( $price_min, $price_max ),
				'type'		=> 'numeric',
				'compare'	=> 'BETWEEN',
			)
		),
		'orderby' => array( 'price_clause' => 'ASC' )
	);

	$custom_posts = get_posts( $args );

	if( ! empty( $custom_posts ) ){
		$output = '<ul>';
		foreach ( $custom_posts as $p ){

			$output .= '<li><a href="' 
			. get_permalink( $p->ID ) . '">' 
			. $p->post_title . '</a> (' 
			. get_post_meta( $p->ID, 'year_published', true ) 
			. ') - Price: ' . get_post_meta( $p->ID, 'price', true ) . '</li>';
		}

		$output .= '</ul>';
	}

return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';

一連のパラメータを定義するために使用する6つのショートコード属性を設定し、これが最終的にWordPressの get_posts 関数へと渡されます。$custom_posts が空でなければ、foreach サイクルは順序付けのないリストのHTMLを生成することになります。

これで、あなたは(そしてあなたのサイトの他の投稿者も)、次のようなショートコードを使用して投稿のリストを表示できるようになります。

[kinsta_get_posts post_type="book" book_category="sci-fi" numberposts="4" price_min=1 price_max=250]

もちろん、引数を好きなように変更して、サイトの任意の投稿またはページでテストを実行することができます。

関数で構築した投稿リスト
関数で構築した投稿リスト

まとめ

WordPressのget_postsは、開発者がWordPressサイトのフロントエンドのどこにでも投稿のリストを表示できるようになる強力な機能です。 WP_Query を使用しますが、使いやすく、投稿のリストだけが必要な場合は WP_Query よりも望ましい選択肢です。投稿をループで表示する必要がある場合は WP_Query を直接参照することをお勧めします。

というわけで、リストを作成し、コードをテストし、問題なく動作することが確認できたら(そこではじめて)、ライブ環境へと適用しましょう(ただし、最初にバックアップを取ることも忘れずに)。

最後に、皆さんからのコメントを楽しみにしています。WordPress  get_posts 関数のご使用/活用例はありますか?実例をご共有ください。以下のコメントからどうぞ!

Carlo Daniele Kinsta

Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.