【WordPress】カテゴリーとタグをAND検索して、検索結果をリアルタイムで表示する

最近趣味でWebサイトを作ろうとしているのですが、タイトルのことを実現するのにものすごく苦労したので、丁寧に残しておこうと思います。
最終的にはシンプルになったのですが、なぜ検索しても出てこないのか不思議でしょうがない。

ちなみに私はITエンジニアではありますが、インフラエンジニアなのでWeb制作関連のことはさっぱりです。
何がJavaScriptで、jQueryで、Ajaxなのかはよくわからないままやっています。普通に難しくね?

目次

ゴール

これが、

こうなって、

こうなるのをゴールにします。
デザインがアレなのは無視してください。苦手なもので。

ちなみに選択する部分の後ろにある数字は、あくまでそのカテゴリーやタグでの記事数なので、リアルタイムでは変わりません。

投稿が存在しない組み合わせが選択された場合は、ちゃんと0になるようにします。

前提条件

項目名項目内容
WordPressバージョン5.8.1
テーマCocoon
親テーマバージョン2.3.7.1
子テーマバージョン1.1.3
環境Windowsのローカル端末上のLocal(Flywheel社)で構築
記事固定ページ
事前知識どうやって実現するかもわからない

とりあえずショートコードでPHPを実行できるようにする

まずは以下のような感じで固定ページを作り、mysearchのショートコードを書いておきます。

mysearchのショートコードを作成するために、子テーマ(cocoon-child-master)のfunctions.phpに以下を追加します。
functions.phpの7行目とかに以下の最上部のようなコメントがあるため、その下に書きます。

//以下に子テーマ用の関数を書く

//検索用コードのショートコード呼び出し用
function mysearch_original() {
    ob_start(); 
    get_template_part('mysearch');
    return ob_get_clean();
}
add_shortcode('mysearch', 'mysearch_original');

次に実際のショートコードの動作部分をmysearch.phpとして作成します。
私は子テーマの直下に置きましたが、格納場所を変える場合は上のfunctions.phpのパスも変えてください。

とりあえず以下でも書いておきます。

<p>ショートコードが実行されています。</p>

これで最初に作成した固定ページを確認すると、以下のようになっているかと思います。
ここまででPHPの内容をショートコードで呼び出せるようになりました。

画像だと固定ページのタイトルや投稿者名などをCSSで消していますが、それについてはまた別の話なので説明しません。

とりあえずAjaxを使ってみる

それではAjax(JavaScript?jQuery?たぶん全部)を使って、リアルタイムにサイト名を表示してみましょう。
mysearch.phpを以下に修正します。

<button id="submit">View Sitename</button>

<div id="search-result-count">サイト名:<span></span></div>

以下のような画面になるはずです。
ボタンを押すとサイト名が表示されるようにします。

functions.phpに以下を追加します。
上はおまじない、下はAjaxから呼ばれる関数です。

// admin-ajax.phpのURLを取得しグローバル変数に設定する
function add_my_ajaxurl() {
?>
    <script>
        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php'); ?>';
    </script>
<?php
}
add_action( 'wp_head', 'add_my_ajaxurl', 1 );

// サイト名を取得して出力するだけの関数
function view_sitename(){
    echo get_bloginfo( 'name' );
    die();
}
add_action( 'wp_ajax_view_sitename', 'view_sitename' );
add_action( 'wp_ajax_nopriv_view_sitename', 'view_sitename' );

Cocoonだと固定ページの編集画面の一番下に、カスタムJavaScriptという入力欄があるかと思います。
そこに以下を追加します。

ボタンが押されたら動作して、Ajax経由でfunctions.phpの関数を実行して、返ってきた値をmysearch.phpのspanタグの間に出力する、ような感じだと思われます。

$( '#submit' ).on( 'click', function(){

    const $count = $('#search-result-count span');

    $.ajax({
        type: 'POST',
        url: ajaxurl,
        data: {
            'action' : 'view_sitename',
        },
        success: function( response ){
            $count.text( response );
        }
    });
    return false;
});

それではボタンを押してみましょう。

表示されました!!

ゴールのコードを実装する

それではゴールのようなリアルタイムのAND検索を実装しましょう。

mysearch.phpを以下のように変更します。
ここまで来れた方なら、説明などはいらないはず(手抜き)。

wp_dropdown_categoriesはお好みで修正してください。
普通に公式?のページ見たらわかると思います。

今後は積極的に更新されないようなので、リンクを貼るのもどうかって感じですが、後継のサイトでは現在のところ英語のページしか無さそうでした。

<form method="get" action="<?php bloginfo( 'url' ); ?>">
<?php wp_dropdown_categories('id=cate&show_option_none=カテゴリー選択&show_count=1&hide_empty=1&exclude=1&hierarchical=1'); ?>
<?php $tags = get_tags(); if ( $tags ) : ?>
    <select name='tag' id='tag'>
    <option value="" selected="selected">タグ選択</option>
    <?php foreach ( $tags as $tag ): ?>
        <option value="<?php echo esc_html( $tag->slug ); ?>"><?php echo esc_html( $tag->name ); ?> (<?php echo esc_html( $tag->count ); ?>)</option>
    <?php endforeach; ?>
</select>
<?php endif; ?>
<input id="submit" type="submit" value="検索" />
</form>

<div id="search-result-count">該当人数:<span></span>人</div>

functions.phpに以下を追加します。
※先ほど追加したview_sitename関数は削除しても大丈夫です。

// カテゴリーIDとタグslug名を受け取り、それをもとに検索、ヒット数を返す
function search_category_and_tag(){
    $cateid = $_POST['cateid'];
    $tagslug = $_POST['tagslug'];

    $args = array(
        'cat' => $cateid,
        'tag' => $tagslug,
    );

    $wp_query = new WP_Query($args);
    echo $wp_query->found_posts;
    die();
}
add_action( 'wp_ajax_search_category_and_tag', 'search_category_and_tag' );
add_action( 'wp_ajax_nopriv_search_category_and_tag', 'search_category_and_tag' );

カスタムJavaScriptを以下に修正します。

$( '#cate, #tag' ).on( 'change', function(){

    const $count = $('#search-result-count span');
    var categories = document.getElementById("cate");
    var tags = document.getElementById("tag");

    $.ajax({
        type: 'POST',
        url: ajaxurl,
        data: {
            'action' : 'search_category_and_tag',
            'cateid' : categories.value,
            'tagslug' : tags.value,
        },
        success: function( response ){
            $count.text(response);
        }
    });
    return false;
});

動作確認する

それでは保存して固定ページで動作確認してみてください。
ゴールの動作になるはずです。
お疲れさまでした。

終わりに

特にまとめもありませんでした。
それでは。

  • URLをコピーしました!

コメント

コメントする

目次