[wp]カスタム投稿の条件付き記事一覧作成方法

カスタムフィールドも対象に。

search.phpではない

search.phpでもカスタム投稿を対象にした検索結果は出力できるけど、カスタム投稿別に絞り込み条件を作るなら項目も変わって使い回せないので今回は使わない。

なお、search.phpでやりたいときは検索部分はこんな感じになる。

<form action="<?php echo home_url(); ?>" method="get">
    <input type="text" name="s" value="<?php the_search_query(); ?>" placeholder="検索ワード">
    <input type="hidden" name="post_type" value="【カスタム投稿スラッグ】">
   <button>検索</button>
</form>

複数の投稿タイプを指定したいならこんな感じ。

<form action="<?php echo home_url(); ?>" method="get">
    <input type="text" name="s" value="<?php the_search_query(); ?>" placeholder="検索ワード">
    <input type="hidden" name="post_type[]" value="【カスタム投稿スラッグ1】">
    <input type="hidden" name="post_type[]" value="【カスタム投稿スラッグ2】">
   <button>検索</button>
</form>

hiddenじゃなくてもいいんで、ラジオボタンなりチェックボックスなりで指定できるようにも作れる。

やりたいこと

  • 特定のカテゴリーやらタグのものを指定する
  • 特定のカスタムフィールドに該当の値があるものを指定する
  • 指定した数値以上、以下みたいな条件で指定する

言ってみれば不動産サイトとか価格.comとかみたいなやつか。

前提というか環境というか

カスタム投稿:Custom Post Type UI

カスタムフィールド:Smart Custom Fields

ページャー:WP-PageNavi

記事一覧の基本形

普通に記事一覧を作るならこんな感じになる。

<?php
$paged = get_query_var('paged')? get_query_var('paged') : 1;
$myQuery = new WP_Query();
$param = array(
    'posts_per_page' => '10',
    'post_type' => '【カスタム投稿スラッグ】',
    'paged' => $paged,
);
$myQuery->query($param);
?>
<?php if($myQuery->have_posts()): ?>
<?php while($myQuery->have_posts()) : $myQuery->the_post(); ?>

<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>

<?php endwhile; ?>
<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(array('query'=>$myQuery)); } ?>
<?php endif; ?>

archive.phpはもちろんのこと、page.phpでもいける。

当然ながら公開済みの記事が新着順で出力される。これに出力条件をつけていく。

複数対応のタクソノミー絞り込み

tax_queryで指定する。

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'タクソノミースラッグ1',
            'field' => 'slug',
            'terms' => array('ターム1','ターム2','ターム3'),
            'operator' => 'IN',
        ),
        array(
            'taxonomy' => 'タクソノミースラッグ2',
            'field' => 'slug',
            'terms' => array('ターム1','ターム2','ターム3'),
            'operator' => 'IN',
        ),
    )
);

operatorが「IN」だと指定したタームのどれかが含まれてたら、という条件になる。そんな感じで色々やれるので、「relation」と「operator」は自分の都合のいいやつに適時変更。

meta_queryもtax_queryも、複数条件を仕込む場合は「relation」が必須なので絶対に忘れないこと。

カスタムフィールドの絞り込み

「該当のカスタムフィールドに指定の値が入ってたら」だとこんな感じ。

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        array(
            'key' => '【カスタムフィールド名】',
            'value' => '【カスタムフィールド値】',
            'compare' => '=',
            'type' => 'CHAR',
        ),
    ),
);

同一フィールドで複数の値を指定することもできる。チェックボックス項目にいいですね。
逆に言うとタクソノミーと違ってタームは1個ずつしか指定できない。

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => '【カスタムフィールド名】',
            'value' => '【カスタムフィールド値1】',
            'compare' => 'LIKE',
        ),
        array(
            'key' => '【カスタムフィールド名】',
            'value' => '【カスタムフィールド値2】',
            'compare' => 'LIKE',
        ),
    ),
);

数値だとこんな感じ。

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        array(
            'key' => '【カスタムフィールド名】',
            'value' => '【カスタムフィールド値】',
            'compare' => '>=', //以上
            'type' => 'NUMERIC',
        ),
    ),
);

数値でやっていくときにはtypeで数字を扱う宣言をしないとだめ。条件指定は一致する・しないだけでなく、以上・以下、未満とかそういうのもいける。

範囲内・範囲外って条件もできる。「◯◯以上〇〇以下」だとこう。

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        array(
            'key' => '【カスタムフィールド名】',
            'value' => array(0,1000), //0~1000だったら
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC',
        ),
    ),
);

このとき、valueの並びは昇順になってないといけない。なので、範囲を入力フォームから拾う場合は順序がイカれることもあるんで、直接突っ込まずに整形するのがいいですね。

$valueArray = array(1000,0);
asort($valueArray);

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        array(
            'key' => '【カスタムフィールド名】',
            'value' => $valueArray,
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC',
        ),
    ),
);

絞り込み用検索フォーム

前述の通り、絞り込みを行うのはsearch.phpじゃない。上記の条件を仕込んだ一覧ページに飛ばすことが大事。で、絞り込みの条件をちゃんと受け取れるようにしなきゃいけない。そこは一般的に使われるgetでいい。

基本形

◯◯~◯◯円だと例えばこんな。

<form action="【該当ページURL】" method="get">
    <input type="text" name="max-num">
    <input type="text" name="min-num">
    <button>送信する</button>
</form>

受け取りと反映はこうなる。

<?php
$min_num = $_GET['min_num'];
$max_num = $_GET['max_num'];
$valueArray = array($min_num,$max_num);
asort($valueArray);

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        array(
            'key' => '【カスタムフィールド名】',
            'value' => $valueArray,
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC',
        ),
    ),
);

記入がない場合の事も考えると、実際の構築には条件分岐が色々追加されることは想像に難くない。$paramに直書きしないで、meta_query内の配列を別で作って放り込む方がいい。

ターム一覧

<form action="【該当ページURL】" method="get">
<?php
    $terms = get_terms('【タクソノミー名】');
    foreach ( $terms as $term ):
    $termName = esc_html($term->name);
?>
    <label><input type="checkbox" name="terms[]" value="<?php echo $termName; ?>"><?php echo $termName; ?></label>
<?php endforeach; ?>

    <button>送信する</button>
</form>

nameに[]を付けてるからそのまま配列として引っ張れるような。

$terms = $_GET['terms[]'];

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'tax_query' => array(
        array(
            'taxonomy' => 'タクソノミースラッグ',
            'field' => 'slug',
            'terms' => $terms,
            'operator' => 'IN',
        ),
    )
);

カスタムフィールド

カスタムフィールドの内容を絞り込みに使いたい場面は自由入力じゃなくて選択肢だろうという前提。

ACFもSCFもカスタムフィールド作成時に選択肢を仕込めるけど、その一覧を表示する機能はないっぽくて、だから手打ちしないといけない。値ごとにベタ打ちするのはダルいからforeachで回すのが最近の自分のトレンド。

<form action="【該当ページURL】" method="get">
<?php
    $fields = array('***','***','***',...);
    foreach ( $fields as $field ):
?>
    <label><input type="radio" name="field" value="<?php echo $field; ?>"><?php echo $field; ?></label>
<?php endforeach; ?>

    <button>送信する</button>
</form>

で、こう。

$field = $_GET['field'];

$param = array(
    'post_type' => '【カスタム投稿スラッグ】',
    'meta_query' => array(
        array(
            'key' => '【カスタムフィールド名】',
            'value' => $field,
        ),
    ),
);

ページネーションとパラメータの話

今回の内容は絞り込み条件をパラメータに突っ込んで扱う方法を取ってる。

記事一覧だからいっぱいヒットする可能性は十分にある。何十件何百件ある記事を全部表示するのは流石にダルいので、ページネーションを入れたい。

パラメータが無いと絞り込みが動かないのだけど、ページネーションと共存できるのか。

結論、できる。

WP-PageNavi
より高度なページ送りナビゲーション用のインターフェースを追加します。

wp-pagenaviが入ってるページでURLにパラメータを足して更新すると、WP-PageNaviが生成したページネーションのリンクにもパラメータが入ってることが分かる。

調整が必要ないのでめっちゃ助かりますね。

データベースから引っ張る方法(SQL)

もはやWordpressの良さをぶち壊しにしてる気がするんだけど、一般的なPHPよろしくDBから直接引っ張る手段がある。

WordPress内の検索対象にカスタムフィールドも適用する | サイテックファクトリー
Advance Custom fields(ACF)で作成した項目を検索する方法 | ガリレオ アンド ヴィーナス合同会社
Advance Custom fields(ACF)で作成したカスタムフィールドの内容は、通常のWordpressの検索では引っかかりません。
WordPressで絞り込み検索!検索機能を拡張してカスタムフィールド・複数カテゴリ・日付範囲で検索できるようにする | WordPressはプロに外注!ワードプレス制作の代行、外注【サイトマネージ】東京都新宿区のWeb制作会社
Wordpressの検索機能ではキーワード検索が可能ですが、 商品情報や店舗情報などを掲載するサイトの場合、た

実用性が無くはないけどなんかもうWP案件なのかこれ?っていうモヤモヤ。

プラグインでやる

VK Filter Search
カテゴリー、タグ、カスタム投稿タイプ、キーワードなどで絞り込める検索機能を、ブロックとして追加するプラグインです。
Search & Filter
カスタム投稿、カテゴリ、タグ、タクソノミー、投稿日、投稿タイプの検索とフィルタリング
WP Custom Fields Search
Build search forms to provide custom search functionality allowing search of built in post fields, custom fields via a v...

探せばもっとある。

ウィジェットとかブロックエディタに放り込めるらしい。カスタム投稿、カスタムフィールドに対応してるらしい。良いですね。ただ、どれもインストール数がそこまでないのでプラグインに頼ることは稀なんでしょう。

最近はプラグインを減らしたい派になってるのでちょっとためらいがある。

コメント

タイトルとURLをコピーしました