WordPressでカスタム投稿のタクソノミー、タームを検索できるようにする

概要

WPで、スタッフ(カスタム投稿)のランク(タクソノミー)やら勤務店舗(タクソノミー)やらをOR検索したい。

【参考サイト】
https://works.coldsleep.jp/blog/search-method/
https://website-fun.com/wp-refine-search/
https://github.com/seebz/Snippets/blob/master/Wordpress/functions/wp_dropdown_taxonomies.php
https://qiita.com/ymeeto/items/7681db1f78d3e0e8301a
https://www.webopixel.net/wordpress/584.html
https://www.akaeho.net/wp-searchform/

やったこと

1.検索用のフォームが必要なのでフォームを作成します。
2.次に検索用フォームの表示。
3.配列の検索結果(メニューのような、いくつも選べるもの)がORで検索されないのでその修正。
4.検索結果を専用の表示ファイルに変更、という感じで作業します。
※検索結果の表示ファイルは(この記事では)作りません。通常だと検索結果はテーマの「search.php」か「archive-カスタム投稿タイプ名.php」とかになるはず。

検索フォーム

検索したい項目を並べた検索用フォームを作成します。
今回は自動でタクソノミーからひっぱってきてもらいます。

テーマ内に【searchform-staff.php】というファイルを作って保存。

<h4>スタッフ検索</h4>

<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
    <!-- name="post_type"のvalueに、検索対象の投稿タイプを記入する。今回は【staff】 -->
    <input type="hidden" name="post_type" value="staff">
    <input type="search" class="hidden-search-field" name="s" value="<?php echo get_search_query(); ?>"/>

    <!-- ラジオボタン -->
    <h4>スタッフランク</h4>
    <label><input type="radio" name="staff_rank" value="" checked="checked">指定なし</label><br/>
    <?php
    $taxonomy_name = 'staff_rank'; // 取得したいタクソノミー名を記入【staff_rank】
    $args = array('hide_empty' => 0); // 紐づく投稿記事がなくても表示する
    $taxonomys = get_terms($taxonomy_name, $args);
    if (!empty($taxonomys) && !is_wp_error($taxonomys)):
        foreach ($taxonomys as $taxonomy):
            ?>
            <label><input type="radio" name="staff_rank"
                          value="<?php echo $taxonomy->slug; ?>"><?php echo $taxonomy->name; ?></label><br/>
        <?php endforeach; ?>
    <?php endif; ?>


    <!-- チェックボックス -->
    <h4>スタッフメニュー</h4>
    <?php
    $taxonomy_name = 'staff_menu'; // 取得したいタクソノミー名を記入【staff_menu】
    $args = array('hide_empty' => 0); // 紐づく投稿記事がなくても表示する
    $taxonomys = get_terms($taxonomy_name, $args);
    if (!empty($taxonomys) && !is_wp_error($taxonomys)):
        foreach ($taxonomys as $taxonomy):
            ?>
            <label><input type="checkbox" name="staff_menu[]"
                          value="<?php echo $taxonomy->slug; ?>"><?php echo $taxonomy->name; ?></label><br/>
        <?php endforeach; ?>
    <?php endif; ?>


    <!-- ドロップダウンリスト -->
    <h4>スタッフ勤務店舗</h4>
    <select name="staff_location">
        <option value="">すべての店舗</option>
    <?php
    $taxonomy_name = 'staff_location'; // 取得したいタクソノミー名を記入【staff_location】
    $args = array('hide_empty' => 0); // 紐づく投稿記事がなくても表示する
    $taxonomys = get_terms($taxonomy_name, $args);
    if (!empty($taxonomys) && !is_wp_error($taxonomys)):
        foreach ($taxonomys as $taxonomy):
            ?><option value="<?php echo $taxonomy->slug; ?>"><?php echo $taxonomy->name; ?></option>
        <?php endforeach; ?>
    <?php endif; ?>
    </select>

    <!-- 検索ボタン -->
    <div>
        <input type="submit" value="検索する">
    </div>
</form>

検索用フォームを表示

検索フォームを表示する際はテーマ内のphpにrequire_onceで表示します。

<?php require_once('searchform-staff.php'); ?>

function.phpの変更

このままだとチェックボックスが配列でデータを渡しているせいかきちんと検索してくれないので「function.php」に下記を追加して文字列にして渡します。

function custom_request($query)
{
    if (!empty($query['staff_menu']) && array_key_exists('s', $query)){
        $query['staff_menu'] = implode(',', $query['staff_menu']);
    }
    return $query;
}
add_filter( 'request', 'custom_request' );

ここまでやると、メニューがOR検索で検索ができるようになりました。

検索結果を別のテンプレートに変更したい場合

スタッフの検索結果は別テンプレートで表示したいときは下記で変更できます。
検索対象のカスタム投稿に、専用のアーカイブがある人はコピーして作ってもいいかも?

「function.php」に下記を追加します。今回はpost typeが【staff】
検索結果表示用ファイルは【search-staff.php】としました。

/**
 * スタッフ検索用検索結果
 */
add_filter('template_include','custom_search_template');
function custom_search_template($template){
    if ( is_search() && is_post_type_archive('staff') ){
        $templates[] = "search-staff.php";
        $template = get_query_template('search',$templates);
    }
    return $template;
}

おわり。

おまけ:ドロップダウンリストの並び順を指定する

ドロップダウンリストを指定の順番で表示させたい場合。
ついでに選択内容を自動選択する。

//選択した内容の取得
$staff_location = filter_input(INPUT_GET, 'staff_location', FILTER_SANITIZE_SPECIAL_CHARS);

//このリストの順番でドロップダウンに表示される
$staff_location_list = array(
    '愛知'=>'',
    '岐阜'=>'',
    '静岡'=>'',
    '徳島'=>'',
);
function create_select_options($list,$taxonomys,$selected_target){
    if (!empty($taxonomys) && !is_wp_error($taxonomys)){
        foreach ($taxonomys as $taxonomy){
            //リストに項目があるか存在チェックして、あればスラッグを入れる
            if(isset($list[$taxonomy->name])){
                $list[$taxonomy->name] = $taxonomy->slug;
            }
        }
        //リストの順にオプションをつける
        foreach ($list as $key => $item){
            //スラッグが空なら存在しないので、処理しない
            if(empty($item)){
                continue;
            }
            //選択していたら「selected」をつける
            $selected = '';
            if ($item === $selected_target) {
                $selected = ' selected';
            }
            //オプション出力
            echo '<option value="' .esc_attr($item). '"' .esc_attr($selected). '>' .esc_html($key). '</option>';
        }
    }
}

設置方法

    <h4>スタッフ勤務店舗</h4>
    <select name="staff_location">
        <option value="">すべての店舗</option>
        <?php
        $taxonomy_name = 'staff_location'; // 取得したいタクソノミーの情報
        $args = array('hide_empty' => 0); // 紐づく投稿記事がなくても表示する
        $taxonomys = get_terms($taxonomy_name, $args);
        //選択項目の表示
        create_select_options($staff_location_list,$taxonomys,$staff_location);
        ?>
    </select>

こんどこそおわり。

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