カスタムフィールドを使っていると、記事検索の条件に使いたいと思う事があります。
そんな時に使えるのがサブクエリです。
ポータルサイトを作る時や、カスタムフィールドに数値データを入力している時に便利です。
WP_Queryクラスを使う
サブクエリの中でも、メインクエリと同じように投稿データを扱う事ができる、WP_Queryクラスを使用します。
今回の内容だけで言えば、get_posts()でも良いんですが。
この先に何か手を加える場合も考えて、WP_Queryで作っておくのが良いかと思います。
サブクエリについては、こちらの記事をご覧ください。
meta_queryで複数のパラメーターを指定する
複数のカスタムフィールドの値をクエリの条件に使う場合は、meta_queryのパラメータを使用するのが便利です。
カスタムフィールドのクエリで使用できるパラメータは以下の通りです。
<?php
$args = array(
'meta_key' => "カスタムフィールドのキー",
'meta_value' => "カスタムフィールドの値(文字列)",
'meta_value_num' => "カスタムフィールドの値(数値)",
'meta_compare' => "テスト演算子",
'meta_query' => array(
'relation' => "複数のカスタムフィールドを指定した場合の関係",
array(
'key' => "カスタムフィールドのキー",
'value' => "カスタムフィールドの値",
'compare' => "テスト演算子",
'type' => "カスタムフィールドの値のタイプ"
),),
);
?>
このパラメータの中から、記事の一覧を呼び出すに必要なものを設定していきます。
今回はHTMLで用意したフォームから送信された値を使って、該当するカスタムフィールドの値を持つ投稿を呼び出すことが目的です。
なので、
・カスタムフィールドのキー
・カスタムフィールドの値
・テスト演算子
で指定します。
なので、HTMLフォームからデータを受け取る側のPHPファイルにこのように書きます。
<?php
$args = array(
'post_type' => 'test', //投稿タイプの指定
'post_status' => 'publish', //公開状態の指定
'orderby' => 'ID', //表示順の指定
'posts_per_page' => -1, //全件表示
'meta_query' => array(
array(
'key' => 'test-text', //カスタムフィールドのnameを指定
'value' => 'hoge', //hogeという値を探す
),),
);
$test_query = new WP_Query( $args );
if( $test_query->have_posts() ):
while( $test_query->have_posts() ):
$test_query->the_post();
?>
カスタム投稿タイプ「test」の公開されている記事の中から、「test-text」というカスタムフィールドの値が「hoge」となっているものをID順に一覧表示する。
という内容です。meta_queryの中で指定していないcompareは初期値が「=」、typeは「CHAR」なので省力しています。
meta_queryはrelationでAND、またはORを使うことで複数のカスタムフィールドを指定することもできます。
<?php
$args = array(
'post_type' => 'test', //投稿タイプの指定
'post_status' => 'publish', //公開状態の指定
'orderby' => 'ID', //表示順の指定
'posts_per_page' => -1, //全件表示
'meta_query' => array(
'relartion' => 'AND', //条件の追加
array(
'key' => 'test-text', //カスタムフィールドのnameを指定
'value' => 'hoge', //hogeという値を探す
),
array(
'key' => 'test-number', //追加する条件のカスタムフィールド名
'value' => 2, //探す数値
'type' => 'numeric', //データの型が数字であることの指定
'compare' => '!=', //valueで指定した値以外
),
),
);
$test_query = new WP_Query( $args );
if( $test_query->have_posts() ):
while( $test_query->have_posts() ):
$test_query->the_post();
?>
relationの初期値はANDなので、ORの時だけ指定するのでも良いです。
これで条件に当てはまる記事一覧を指定することができます。
条件分岐を入れておく
自分が少しハマった経験もあるのですが、HTMLフォームから渡された値が空の場合、動作しない場合があります。
条件検索の場合は、選択されない項目がある場合があるからです。
なので、meta_queryで指定するパラメータを受け取っているかどうかで条件判定しておくと良いです。
<?php
$post_value = filter_input( INPUT_POST, 'フォームから受け取る値のあるname属性' );
$args = array(
'post_type' => 'test', //投稿タイプの指定
'post_status' => 'publish', //公開状態の指定
'orderby' => 'ID', //表示順の指定
'posts_per_page' => -1, //全件表示
);
if( !empty( $post_value ) ){
$args += array(
'meta_query' => array(
array(
'key' => 'test-text',
'value' => 'hoge',
),
),
);
}
?>
まずは、元となるクエリを最初に指定します。
これで、条件が指定されていない場合は、呼び出す投稿タイプの投稿一覧が表示されます。
そして、HTMLフォームから受け取った値があるかどうかを、empty()で判定します。
この書き方であれば、「値があれば」となります。
値があった場合に、クエリのパラメータに追加するmeta_queryのパラメータを指定する。
という流れとなっています。
変数を使う時の「=」の前に「+」を付ければ、追加してくれます。
後はループの内容とクエリの終了
ということで。今回のコード全文です。
<form method="post" action="htttps://test.com/" >
<input type="text" name="test-form" value="hoge"/>
</form>
HTMLフォームは適当に用意したものなので、チェックボックスやセレクトボックス、ラジオボタンで実装すると良いです。
<?php
$post_value = filter_input( INPUT_POST, 'フォームから受け取る値のあるname属性' );
$args = array(
'post_type' => 'test', //投稿タイプの指定
'post_status' => 'publish', //公開状態の指定
'orderby' => 'ID', //表示順の指定
'posts_per_page' => -1, //全件表示
);
if( !empty( $post_value ) ){
$args += array(
'meta_query' => array(
array(
'key' => 'test-text',
'value' => 'hoge',
),
),
);
}
$test_query = new WP_Query( $args );
if( $test_query->have_posts() ):
while( $test_query->have_posts() ):
$test_query->the_post();
?>
<h2><?php echo the_title(); ?></h2>
<p><!-- 呼び出したいものを書いて行く --></p>
<?php endwhile; ?>
<?php endif;?>
<?php wp_reset_postdata(); ?>
これでクエリで絞り込んだ記事一覧の表示ができます。
また、カスタムフィールドに何らかの数値を保存している場合、その集計を行う事もできます。
その場合は、wp_reset_query()の前までに書いておくと良いです。
地味にはまった思い出
と、このようにコードを書き構文エラーは出てないんだけど、表示されない・・・
ということで地味にはまってた事があります。
原因は、カスタム投稿に保存されている値と、HTMLフォームから送信した値がずれていたことでした。
送る値とカスタム投稿に保存する値は確認しないといけませんね笑
オリジナルの条件付検索の実装方法でした
運営するWEBサイトの内容にもよりますが、条件検索を用意しておくと読者が便利にサイトを使う事ができるツールの一つとなります。
必要になった時の参考になればと思います。