Wordpressにpageテンプレートで検索機能を実装する

# はじめに

※この記事は「[カスタム投稿タイプをゼロから作ってウェブサイト上に表示させるまで](https://qiita.com/yomogenium/items/32979df92721483a81e1)」
の続きだったりします。


この記事では**search.phpを使わずに、独自の検索機能を作成する**方法について解説していく。


もくじ

- [ステップ１：検索内容の入力ページ、出力ページをつくる](https://qiita.com/yomogenium/items/e8d74e87c2815e6db4ed#%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%EF%BC%91%E6%A4%9C%E7%B4%A2%E5%86%85%E5%AE%B9%E3%81%AE%E5%85%A5%E5%8A%9B%E3%83%9A%E3%83%BC%E3%82%B8%E5%87%BA%E5%8A%9B%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B)
 - [ステップ２：検索文字を入力するフォーム、検索結果画面をつくる　～～　検索内容入力画面](https://qiita.com/yomogenium/items/e8d74e87c2815e6db4ed#%E6%A4%9C%E7%B4%A2%E5%86%85%E5%AE%B9%E5%85%A5%E5%8A%9B%E7%94%BB%E9%9D%A2)
 - [ステップ２：検索文字を入力するフォーム、検索結果画面をつくる　～～　検索結果画面](https://qiita.com/yomogenium/items/e8d74e87c2815e6db4ed#%E6%A4%9C%E7%B4%A2%E7%B5%90%E6%9E%9C%E7%94%BB%E9%9D%A2)


#ステップ１：検索内容の入力ページ、出力ページをつくる

詳細なやり方は[前回の記事](https://qiita.com/yomogenium/items/32979df92721483a81e1#ステップ２一覧ページの作成)に詳しいが、一応おさらい。

####固定ページの作成・おさらい

phpファイル「`page.php`」をダウンロードし、
ファイル名を「page-任意の半角英数字.php」に書き換える。
ここでは、検索文字の入力欄ページを「`page-s_form.php`」、検索結果ページを「`page-s_result.php`」としよう。

ファイルの中身をそれぞれ以下のようにし、

```php:page-s_form.php
<?php
/**
* Template name: page-s_form.php
*/
get_header(); ?>


<?php get_footer(); ?>
```


```php:page-s_result.php
<?php
/**
* Template name: page-s_result.php
*/
get_header(); ?>


<?php get_footer(); ?>
```

これらをアップロードしたら、Wordpressの管理画面から「固定ページ」→「新規追加」。
出てきた画面で任意のタイトルを入力して編集ページに入り、「固定ページの属性」の中の「テンプレート」から、先ほど指定した名前を選択。
右側の「公開」ボタンを押せば、準備完了だ。




#ステップ２：検索文字を入力するフォーム、検索結果画面をつくる


##検索内容入力画面

それぞれのコードは以下のようになる。

```php:page-s_form.php
<?php
/**
* Template name: page-s_form.php
*/
get_header(); ?>



    <form method="get" action="<?php echo home_url('/'); ?>/s_result">

            <input name="s" type="text" id="searchtxt" placeholder="ここに検索語句を入力" >

            <input type="submit" value="検索する！">
    
    </form>

<?php get_footer(); ?>
```

入力画面はあくまで単なる「文字を入力するだけのページ」であり、ここで特別な処理を行うわけじゃあない。
注意すべきは、`form`タグについている`action`属性。

「検索する！」ボタンを押したとき、入力された語句はこのactionに書かれたページへと渡され、ページ自体もactionに記入されたURLに移動するというシステムで成り立っているhtmlの特性上、このaction属性内には**検索結果画面の正しいURLを記入しなくてはならない**のだ。

今回は検索結果のページURLを「`https://ドメイン名/s_result`」ということにしているので、`<?php echo home_url('/'); ?>/s_result`と記入。もちろん、あなたが検索結果ページのパーマリンクを「`s_result`」に設定しているなら、このコードはそのままコピペして大丈夫だ。


##検索結果画面

で、お次は検索結果のページ。
検索処理は基本的にこちらの側で行う。

大きく二段階の処理に分かれていることに注意しよう。


```php:page-s_result.php
<?php
/**
* Template name: page-s_result.php
*/
get_header(); ?>



<?php

// ~~~~~~~~~~~~~~~~~~~~データベースから条件に合った投稿情報を取得するコード

// 検索文字列を配列に格納
$searchwords = explode(array(" ", "　"), $_GET['s']);

// 投稿を検索。ここでは、「入力された文字列の中にタイトルと一つでも一致するpostがあれば表示」という方式。
$searchrule = array(
	'post_type' => 'post',
	'title' => $searchwords,
	'compare' => 'IN'
);
$resultquery = new WP_Query( $searchrule );




// ~~~~~~~~~~~~~~~~~~~~取得してきた投稿情報を出力するコード


// 検索に使った語句を表示
if ( $resultquery->have_posts() ) :
	?>
	<h1 class="page-title"><?php foreach($searchwords as $value){ echo $value.'、'}; echo 'の検索結果'; ?></h1>
	<?php
endif; ?>




<?php
// ヒットした検索結果を表示したい場合
if( $resultquery->have_posts() ):
	while( $resultquery->have_posts() ) : $resultquery->the_post(); ?>
		<!-- 該当する投稿が１つ以上あったときの処理。 この中のものを繰り返し表示する。-->
		<div>
			<!-- 投稿のタイトル -->
			<h2><?php echo get_the_title(); ?></h2>

			<!-- 投稿の個別ページへのリンク -->
			<a href="<?php echo get_permalink(); ?>">ここから移動</a>

		</div>
		<!-- ここまで -->
		<?php
	endwhile;
else:
?>
<!-- 見つからなかったときの処理～ -->

<div>
	<p>ごめんなさい、お探しのページは見つかりませんでした……</p>
</div>

<!--  ～見つからなかったときの処理 -->
<?php
endif; ?>


<?php get_footer(); ?>
```



#おまけ

勘のイイ人ならお気づきだろうけど、これ、ある部分をカスタマイズすれば検索範囲を自在に変更することができる。

```php:page-s_result.php
<?php

// ~~~~~~~~~~~~~~~~~~~~データベースから条件に合った投稿情報を取得するコード


// 検索文字列を配列に格納
$searchwords = explode(array(" ", "　"), $_GET['s']);

// 投稿を検索
$searchrule = array(
	'post_type' => 'dessert',
	'meta_key' => 'sweets_type',
	'meta_value' => $searchwords,
	'compare' => 'IN'
);
$resultquery = new WP_Query( $searchrule );

?>
```

ようするに、要領はクエリ操作とまったく同じなのだ。



また、検索結果画面はこういう書き方もできる。
これを使えば、「新しい投稿がされるたびに同名の投稿がないかどうかチェックして、同じタイトルの投稿があったら警告してくれる機能」みたいな応用的な機能だって実装できる。（その場合、functions.phpに書き込まないといけないんだけどね……）


```php:page-s_result.php
<?php
// ~~~~~~~~~~~~~~~~~~~~データベースから条件に合った投稿情報を取得するコード

// 検索文字列
$searchwords = array("日記その１", "日記その２");

// 投稿を検索。ここでは、「入力された文字列の中にタイトルと一つでも一致するものがあれば表示」という方式。
$searchrule = array(
	'post_type' => 'post',
	'title' => $searchwords,
	'compare' => 'IN'
);
$resultquery = new WP_Query( $searchrule );


// ~~~~~~~~~~~~~~~~~~~~取得してきた投稿情報を出力するコード


// ヒットした検索結果を表示はせず、オブジェクトに格納したい場合
$resultinfo = $resultquery->posts;



?>
```