特定のカスタム投稿のみ検索できるように本来のPHPの仕様と固定ページを利用して実装する方法

何がしたいか

もともと検索フォームが設置されているサイトにおいて、新たに店舗検索用にカスタム投稿(shop)を作成しました。

店舗検索したいのに、他の投稿が混ざってたら店舗検索しずらいのでカスタム投稿(shop)の店舗のみを検索できるようにしたい。(検索をかけた時に通常の投稿は検索にかからず、カスタム投稿(shop)のみに検索がかかるようにしたい)

解決方法

wordpressを切り離し、本来のPHPの使用も混ぜて作成していく。

固定ページを作成

slugをsearch-shopにして固定ページを作成。

page-search-shop.php

検索ボックス作成

まずカスタム投稿タイプ”shop”のアーカイブページに検索ボックスを設置。

actionにはフォームの送り先として固定ページ(page-search-shop.php)を指定。

<div class="search-box">
  <form method="get" action="<?php echo home_url('search-shop'); ?>">
    <input type="text" name="shopresult" value="<?php the_search_query(); ?>" placeholder="店舗を検索" />
    <button type="submit" class="search-btn">検索</button>
  </form>
</div>
php
//検索されたワードをshopresultの値として出力する(東京と検索されたらvalue="東京"になる。動的に値を設定できる)
value="<?php the_search_query(); ?>"

検索結果を表示する

検索結果は固定ページ(page-search-shop.php)で出力。

フォームを受け取るのにget_search_query()ではなく、PHPで使われる$_GET[]を使う。

  <?php
    $args = array(
      'post_type' => 'shop',
      'posts_per_page' => -1, //表示数
      's' => $_GET['shopresult'], 
      //カスタムフィールドも検索に含まれる(プラグイン: ACF: Better Search)
    );
    $wp_query = new WP_Query($args);
    
    if ( $wp_query->have_posts()): while ( $wp_query->have_posts()): $wp_query->the_post();
  ?>

    <a href="<?php the_permalink(); ?>">
      <h2 class="search-result__ttl"><?php the_title(); ?></h2>
      <p class="search-result__open"><?php echo post_custom('open') ?></p>
      <p class="search-result__address"><?php echo post_custom('address') ?></p>
    </a>
    <?php endwhile; ?>
  <?php else: ?>
    <p>キーワードはみつかりません。</p>
  <?php endif; ?>
  <?php wp_reset_postdata(); ?>

検索にかけられた文字列を‘s’ => $_GET[‘shopresult’]で取得・設置します。

functions.phpの怪しい記述をコメントアウト

// Site Search Page unset
if (!function_exists('SearchFilter')) {
	function SearchFilter($query) {
	if ($query->is_search && !is_admin()) {
	// $query->set('post_type', 'post');
	}
	return $query;
	}
	add_filter('pre_get_posts','SearchFilter');
}

上記の記述はStorkにもともと入っているものなのか、誰かが記述したものなのかは分かりませんが一応メモとしてこのブログにも載っけておきます。

$query->set(‘post_type’, ‘post’);の部分をコメントアウトして無効化しました。

検索結果にカスタムフィールドの値も含めたい

通常の検索では、タイトルとコンテンツのみを検索に含むので、カスタムフィールドの値は検索に含まれません

色々調べた結果、どうやらSQL文を操作するしかなさそう…。

ちょっと個人的には難易度が高かったので、プラグインを利用することにしました。

カスタムフィールドはACF(Advanced Custom Fields)のプラグインを利用していたので、

ACF: Better Searchというプラグインを利用することにしました。

設定ですが、検索に含みたいフィールドタイプにチェックを入れてみました。

デフォルトで以下画像の通りチェックが入っています。

お好みでチェックをつけるといいと思います。

うまくいかなかったコード(念のためメモとして残す)

上記を実現するためにwordpressの仕様をうまく利用して実装する例を以下のリンクより参照し、実装してみたのですがうまくいかず。他のサイトでも同じ手法が使われていましたので、通常は以下のリンクの通りに実装したら正常に動作するのかもしれません。

うまくいかなかった時に利用していたテーマはstorkです。

一応うまくいかなかったコードを以下のアコーディオンに隠しておきます。(わたしがあとで見るかもしれないから念のためメモ)。

他のテーマでは正常に動くかもしれないので。

検索ボックス作成

<div class="search-box">
  <form method="get" id="search" action="<?php echo home_url('/'); ?>">
    <input type="text" name="s" id="search-input" value="<?php the_search_query(); ?>" placeholder="店舗を検索" />
    <input type="hidden" name="post_type" value="shop">
    <button type="submit" accesskey="f" class="search-btn">検索</button>
  </form>
</div>

name=’s’はwordpress特有の記述の模様。search.phpを取り出そうとする。

search-shop.phpが使えるようにfunction.phpに追記

デフォルトではsearch-{post_type}.phpは使えないので使えるようにするためにfunctions.phpに追記する。

//カスタム投稿タイプの検索
add_filter('template_include','custom_search_template');
function custom_search_template($template){
  if ( is_search() ){
    $post_types = get_query_var('post_type');
    foreach ( (array) $post_types as $post_type )
      $templates[] = "search-shop.php";
      $templates[] = 'search.php';
      $template = get_query_template('search',$templates);
     }
  return $template;
}

検索結果を表示する

<?php
    $args = array(
      'post_type' => 'shop',
      'posts_per_page' => -1, //表示数
      's' => get_search_query(), //name="s"のです
    );
    $wp_query = new WP_Query($args);
    if ( $wp_query->have_posts()): while ( $wp_query->have_posts()): $wp_query->the_post();
  ?>
	  //ループするコンテンツ↓
    <a href="<?php the_permalink(); ?>">
      <h2 class="search-result__ttl"><?php the_title(); ?></h2>
      <p class="search-result__open"><?php echo post_custom('open') ?></p>
      <p class="search-result__address"><?php echo post_custom('address') ?></p>
    </a>
    <?php endwhile; ?>
  <?php else: ?>
    <p>キーワードはみつかりません。</p>
  <?php endif; ?>
  <?php wp_reset_postdata(); ?>

post_typeをget_query_var(‘post_type’)にしてもshopにしてもなぜかpostを引っ張ってきてしまう….。

‘s’はsearch.phpを取り出そうとする模様。これはwordpressの使用??sを使わない方がよいかも…。