2012年10月07日
CSVを利用してカスタムオブジェクトやエントリを条件指定検索する
PowerCMSではエントリー(ブログ記事/ウェブページ)の詳細検索(カテゴリのAND OR検索に対応)が可能で、EnterpriseエディションのPowerSearchを利用すれば、さらに詳細な条件指定検索(カスタムフィールドや日付指定等の詳細指定)が可能です。また、MTSearchEntries、MTSearchEntryFieldといったブロックタグや、MTSearchCustomObjects、MTSearchCustomObjectFieldといったカスタムオブジェクトを検索するタグが用意されています。
- カスタムオブジェクトをカスタムフィールドの値で検索する
- ランディングページの画像を検索キーワードで切り替える
- 様々な条件を指定したカスタム検索をテンプレートのみで実装する
- MTSearchEntriesとMTSearchEntryField、エントリを絞り込むための2つのブロックタグ
このエントリでは、Standard/Professional等のエディションでカスタムフィールドを指定した複雑な検索を行いたい場合や、MTやPowerCMS標準のアーカイブでは実現できないようなアーカイブを作成したい場合に、CSVを利用した検索の実現方法をご紹介します。
データ量がそんなに多くなければDBへのクエリも発行しないので軽量、手軽に導入できると思います。
インデックス・テンプレートでCSVを作成する
「Book」というカスタムオブジェクトの名前、本文、カスタムフィールド(MTBookAuthor)、日付の値をCSVで出力します。データの更新をリアルタイムに反映させるためには再構築のトリガーを設定してください。
テンプレートは以下のように書きます。
<MTBooks>"<MTBookName regex_replace='/(?=")/g','\\'>","<MTBookBody regex_replace='/(?=")/g','\\' regex_replace='/(?:\r?\n|\r)/g','\n'>","<MTBookAuthor regex_replace='/(?=")/g','\\'>","<MTBookAuthoredOn>"<MTFor regex_replace='/(?<!\r)\n|\r(?!\n)/','\r\n'>
</MTFor></MTBooks>
ダブルクォート (") をPHPのfgetcsv()関数のためバックスラッシュでエスケープする(\")ためにregex_replace='/(?=")/g','\\'さらに、本文欄のようにテキストエリアになっていて改行が許容される欄は regex_replace='/(?:\r?\n|\r)/g','\n' を追加します。
CSVを検索するテンプレートを作成する
SearchCSVプラグインをインストールします。このプラグインにはPHP 5.3以降が必要です。MTSearchCSVテンプレートタグのループの中では、mt:varタグで __item_+数字 にCSVの各セルの値が格納されます。
<MTDynamicMTML>
<MTSearchCSV file="/var/www/html/csv/book.csv" cell="0","1","2" regex="/CMS/","/CMS/","/野田/" sort_by="3" and_or="or" sort_order="descend">
<mt:if name="__first__"><ul></mt:if>
<li>
<dl><dt><mt:var name="__item_0"></dt>
<dd>本文:<mt:var name="__item_1"><br />
著者:<mt:var name="__item_2"></dd>
</dl>
</li>
<mt:if name="__last__"></ul></mt:if>
</MTSearchCSV>
</MTDynamicMTML>
regexモディファイアには正規表現が指定できるため、例えば下記のようなテンプレートを記述することで年での絞り込みが可能です。
例えばウェブサイト配下のオブジェクトを束ねて年を指定したアーカイブや、フォルダやタグでの絞り込み等、柔軟な一覧表示が可能になります。
<MTDynamicMTML>
<MTSearchCSV file="/var/www/html/csv/book.csv" cell="3" regex="/^2012/" sort_by="3" and_or="or" sort_order="descend">
...
</MTSearchCSV>
</MTDynamicMTML>
クエリパラメタによる動的な検索
MTQueryタグと併用することで、フォームから検索条件を指定して検索する動的な検索も可能です。
regexモディファイアに変数の配列を渡す部分に少し工夫が必要です(添字[]による指定)。
<MTDynamicMTML>
<h1>'<mt:Query key="q" escape="html">'の検索結果</h1>
<form method="get" action="search.html">
キーワード : <input type="text" value="<mt:Query key="q" escape="html">" name="q" />
<input type="submit" value="検索" />
</form>
<mt:SetVarBlock name="query[0]">/<mt:Query key="q" preg_quote="1">/</mt:SetVarBlock>
<mt:SetVarBlock name="query[1]">/<mt:Query key="q" preg_quote="1">/</mt:SetVarBlock>
<mt:SetVarBlock name="query[2]">/<mt:Query key="q" preg_quote="1">/</mt:SetVarBlock>
<MTSearchCSV file="/var/www/html/csv/book.csv" cell="0","1","2" regex="$query" sort_by="3" and_or="or" sort_order="descend">
...
</MTSearchCSV>
</MTDynamicMTML>
追記: 正規表現のメタ文字をエスケープするモディファイア preg_quote を追加しました。
コメントを投稿する