【MT】MovableTypeで「地域」と「価格」での絞り込み検索機能を実装する方法

#はじめに

MovableType（以下、MT）にプラグインを導入して検索機能を実装したときの覚書です。
今回、紹介する方法は「地域」と「価格」だけではなく、様々な検索が可能です。

MTの標準機能では、複雑な組み合わせ検索ができないため、各種プラグインを導入して対応しました。

#目的

今回、不動産サイトのように「地域」と「価格」で絞り込みできる検索機能を実装します。
ユーザーは、「地域」と「価格」のそれぞれの項目選び、該当する物件を探せるようにすることが、今回の目的です。

#構築環境・プラグイン・カスタムフィールド

MT上で、「新築」と「中古」というカテゴリを設定したと仮定します。
カスタムフィールドで「地域」と「価格」という項目を作り、検索機能を実装します。

##構築環境

|名称|バージョン|
|:--|:--|
|MovableType|6.2.6|

##プラグイン

今回、導入するプラグインは、全て藤本氏が開発したプラグインになります。
藤本氏は、MT公式の[プラデミー賞](https://www.movabletype.jp/blog/2015-pludemy-goes-to.html)で上位入選するプラグインを多数開発されている方です。
いつも便利なプラグインありがとうございますm(__)m
プラグインを利用する前にライセンス等の確認を行い、遵守してください。
下記に今回導入したプラグイン一覧を掲載しておりますが、リンク先はプラグインの解説ページです。
解説ページ内にダウンロードのリンク先が記載されておりますが、最新のバージョンではないこともあるので、プラグインのダウンロードは、「[プラグイン一覧（※ページ下部に記載）](http://www.h-fj.com/mtplugins/)」から行ってください。

|名称|主な機能|
|:--|:--|
|[SearchEntries 1.11](http://www.h-fj.com/blog/mt5plgdoc/searchentries.php)|カテゴリ・タグ・カスタムフィールドを組み合わせた複雑な条件でも検索を可能するプラグイン|
|[NumericCustomFields 1.00](http://www.h-fj.com/blog/archives/2009/02/21-145227.php)|数値型のカスタムフィールドを追加するプラグイン|
|[GetQueryParam 1.14](http://www.h-fj.com/blog/archives/2008/02/19-134955.php)|フォームに入力された値を読み取るプラグイン|
|[RealtimeRebuild 1.82](http://www.h-fj.com/blog/archives/2007/09/05-174536.php)|ページにアクセスがあったときにテンプレートをリアルタイムに再構築するプラグイン|
|[RebuildHelper 1.06](http://www.h-fj.com/mtplugins/rebuildhelper.php)|RealtimeRebuildプラグインの動作を補助するプラグイン|

プラグインは、基本的にMTのインストールフォルダ内にある `plugins` にアップロードすれば動作します。

SearchEntriesに関しては、`plugins` の他に `mt-static / plugins` にもアップロードするファイルがあります。
また、[解説ページ](http://www.h-fj.com/blog/archives/2010/04/03-102819.php)通りに `lib / MT / ObjectDriver / Driver / DBI.pm`の記述を変更してください。

RealtimeRebuildに関しては、プラグインをアップロードした後に、`mt-realtime-rebuild.cgi` のパーミッションを`705`など適宜変更してください。

##カスタムフィールド

今回、MTのウェブサイトに下記のカスタムフィールドを作成しました。

|システムオブジェクト|名前|種類|オプション|ベースネーム|テンプレートタグ|
|:--|:--|:--|:--|:--|:--|
|記事|地域|ドロップダウン|東京,千葉,埼玉,神奈川|entryarea|EntryArea|
|記事|価格|整数 ※1|　|entryprice|EntryPrice|

※1 NumericCustomFieldsプラグインを導入することで「整数」の項目が追加されます。

#検索画面

##インデックステンプレートの作成

検索画面のインデックステンプレートを作成します。
詳細は、プラグインの公式サイト「[ブログ記事詳細検索プラグイン（その16・検索フォーム作成の基本）](http://www.h-fj.com/blog/archives/2010/05/01-094400.php)」に記載されています。

テンプレート名は、任意で決めてください
下記を記述して保存します。

```html:インデックステンプレート
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>検索画面</title>
</head>

<form method="get" action="<$mt:RealtimeRebuildCGIPath$>">
<input type="hidden" name="tmpl_id" value="<$mt:GetTemplateId tmpl_name="検索結果（新築）"$>" />

    <h1>地域</h1>
	<ul>
		<li><input type="checkbox" name="area" value="東京"> 東京</li>
		<li><input type="checkbox" name="area" value="千葉"> 千葉</li>
		<li><input type="checkbox" name="area" value="埼玉"> 埼玉</li>
		<li><input type="checkbox" name="area" value="神奈川"> 神奈川</li>
	</ul>

	<h1>価格</h1>
	<select name="price_min">
		<option value="1">下限なし</option>
		<option value="1000000">100万円</option>
		<option value="5000000">500万円</option>
		<option value="10000000">1000万円</option>
	</select> ～ 
	<select name="price_max">
		<option value="999999999999">上限なし</option>
		<option value="1000000">100万円</option>
		<option value="5000000">500万円</option>
		<option value="10000000">1000万円</option>
	</select>

	<input type="submit" value="物件探す">

</form>

<body>
</body>
</html>
```

プラグインの公式サイトで説明されていますが、主要箇所のみ解説します。

###ポイント1

`form`の`action`属性には`<$mt:RealtimeRebuildCGIPath$>`を指定します。
決まり文句です。

###ポイント2

`mt:GetTemplateId`の`tmpl_name`には検索結果を表示するテンプレートモジュールの名前を入力します。
この後に検索結果のテンプレートモジュールを `検索結果（新築）` という名前で作成しますので、ここでは`<$mt:GetTemplateId tmpl_name="検索結果（新築）"$>`と記述します。

#検索結果

##テンプレートモジュールの作成

検索結果のテンプレートモジュールを作成します。
今回は、ユーザーが選択した「地域」と「価格」に該当し、カテゴリが「新築」のみの物件のみ表示される検索結果を作成します。

詳細は、プラグインの公式サイト「[ブログ記事詳細検索プラグイン（その17・検索結果表示テンプレート作成の基本）](http://www.h-fj.com/blog/archives/2010/05/02-100257.php)」に記載されています。

テンプレート名は任意で決められますが、検索画面で入力したテンプレート名と同じくするために `検索結果（新築）` と入力します。
下記を記述して保存します。

```html:テンプレートモジュール：検索結果（新築）
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>検索結果（新築）</title>
</head>

<h1>新築物件を探す</h1>

<$mt:GetQueryParamsToVars$>

<mt:SearchConditions>
	<mt:SearchConditionCFSection field="entryarea">
		<$mt:SearchConditionCFValues values="$qp_area"$>
	</mt:SearchConditionCFSection>
	<mt:SearchConditionCFSection field="entryprice">
		<$mt:SearchConditionCFCompare ge="$qp_price_min" lt="$qp_price_max"$>
	</mt:SearchConditionCFSection>
	<mt:SearchConditionCategorySection>
		<$mt:SearchConditionCategory category="新築"$>
	</mt:SearchConditionCategorySection>
</mt:SearchConditions>

<mt:IfNonZero tag="SearchLoadedEntryCount">

	<ul>
		<MTEntries sort_by="field:entryprice" sort_order="ascend">
		<li>
			<p><$mt:EntryTitle$></p>
			<p>地域：<mt:EntryArea></p>
			<p>価格：<mt:EntryPrice></p>
		</li>
		</MTEntries>
	</ul>
	
	<mt:Else>
		
	<p>該当する物件はありません。</p>

</mt:IfNonZero>

<body>
</body>
</html>
```

プラグインの公式サイトで説明されていますが、主要箇所のみ解説します。

###ポイント1

`<$mt:GetQueryParamsToVars$>`を記述することで、入力された値を取得することができます。
検索フォームのチェックボックスで選択された値がコンマで区切られて、「`qp_フィールド名`」の変数に代入されます。
そのため、選択された地域の値は、`$qp_area`の変数に代入されています。
ユーザーが選択した下限価格は、`$qp_price_min`という変数に、上限価格は`$qp_price_max`という変数に代入されています。

###ポイント2

検索条件は、`<mt:SearchConditions>`と`</mt:SearchConditions>`の間に記述します。
検索条件の指定方法は、解説ページをご覧ください。

###ポイント3

`mt:SearchConditionCFSection`の`field`には比較するカスタムフィールドのベースネームを記述します。
今回は地域のカスタムフィールドの値に選択された地域が含まれているかどうか判定するために、`<mt:SearchConditionCFSection field="entryarea">`と記述しています。

`mt:SearchConditionCFValues`の`values`に複数の値を入れる場合は、コンマ区切りで指定します。
例えば、東京と千葉に該当する地域だけを表示したい場合は、`<$mt:SearchConditionCFValues values="東京,千葉"$>`と指定します。
今回は、ユーザーの選択によって地域を指定するため、選択した値が代入されている `$qp_area` を指定しています。

###ポイント4

`mt:SearchConditionCFCompare`では数値の比較が可能です。
「値が○○以上□□以下等」で比較したいときは、`<$mt:SearchConditionCFCompare 演算子1="値1" 演算子2="値2"$>`と記述します。
演算子については、「[MTIf](https://www.movabletype.jp/documentation/appendices/tags/if.html)」に説明があります。
※SearchEntriesプラグインで上述したページに記載がある全ての比較演算子が使えるかは未検証です。

`ge="値1"`で`値1`以上となり、`lt="値2"`で`値2`よりも小さい場合となります。
今回は、ユーザーの選択によって下限価格と上限価格を指定するため、`<$mt:SearchConditionCFCompare ge="$qp_price_min" lt="$qp_price_max"$>`と記述しています。

比較に関する詳細は、[解説ページ](http://www.h-fj.com/blog/archives/2010/04/12-092730.php)をご覧ください。

###ポイント5

~~~
	<mt:SearchConditionCategorySection>
		<$mt:SearchConditionCategory category="新築"$>
	</mt:SearchConditionCategorySection>
~~~

この3行ではカテゴリを指定しています。
`新築`に該当する記事のみが表示されます。

##RealtimeRebuildプラグインの設定

検索結果のテンプレートモジュールの作成したらRealtimeRebuildプラグインの設定を行います。
「ツール > プラグイン > RealtimeRebuild」から「設定」を選びます。
テンプレート一覧が表示されているので、 [テンプレートモジュール]検索結果（新築）にチェックして、「変更を保存」を選択します。

###設定するときの注意点

+ プラグインの公式サイトにも記載されていますが、関係ないテンプレートはチェックしないでください。
+ このRealtimeRebuildプラグインの設定をしないと、「`テンプレートを読み込むことができませんでした。 at /home/xxx/xxx/plugins/RealtimeRebuild/lib/RealtimeRebuild.pm line 65.`」というエラーが表示されるので、検索結果を表示するテンプレートは必ずチェックしてください。
+ おそらく、テンプレートの作成とチェックする順番も関係するので、チェックしてもエラーが表示される場合は、テンプレートなどを再度保存してみてください。

#ちなみに

該当する記事がないと「`再構築に失敗しました。`」などのエラーが表示されます。

#参考書籍

今回、導入したプラグインの開発者である藤本氏の著書「[MovableType5 実践テクニック](http://www.sbcr.jp/products/4797358834.html)」が書籍として参考になります。
MovableType5ですが、プラグインの使い方は、基本的に同じなので、検索機能を実装したい方は参考になると思います。