とあるサイトで検索機能を追加することになった。
前にもこのサイトで作ったじゃないか!というのは置いといて、今回のケースでもまぁ聞いてくれ。
今回のサイトでは、日誌のブログと辞書のブログの二つのブログページを運用している。
当然、検索した時も二つのブログページを合わせて結果一覧を出したいもの。
しかし、前のスクリプトモジュールブロックだと何かと都合が悪い。
というわけで、何でもできるcms:moduleで検索結果ページを作ってみた。
SOY CMSでどのページでも使えるブログのサイドバーを作ってみた
はじめに、

管理画面のモジュール管理でモジュールを作成します。
この時作成するのはPHPの記述ができる方です。
ここで作成したモジュールのタグを、

http://kyonou.com/contents/search?q=鶏糞
検索結果を表示したい箇所に貼り付けます。
ここまで設置できたら、次はモジュールの方を見ていきます。
モジュールに書いたスクリプトは下記の通り
$html = array();
$html[] = "<h2>検索結果</h2>";
if(!isset($_GET["q"]) || strlen(trim($_GET["q"])) === 0) return array();
$query = htmlspecialchars(trim($_GET["q"]), ENT_QUOTES, "UTF-8");
$sql = "SELECT entry.title, entry.alias, label.label_id FROM Entry entry ".
"INNER JOIN EntryLabel label ".
"ON entry.id = label.entry_id ".
"INNER JOIN EntryAttribute attr ".
"ON entry.id = attr.entry_id ".
"WHERE label.label_id IN (2, 3) ".
"AND (entry.title LIKE :query OR entry.content LIKE :query OR entry.more LIKE :query) ".
"AND entry.isPublished = 1 ".
"AND entry.openPeriodEnd >= :now ".
"AND entry.openPeriodStart < :now ".
"ORDER BY entry.cdate desc ";
$binds = array(
":query" => "%" . $query . "%",
":now" => time()
);
$dao = new SOY2DAO();
try{
$results = $dao->executeQuery($sql, $binds);
}catch(Exception $e){
$results = array();
}
if(count($results)){
$html[] = "<ul>";
foreach($results as $res){
if(!isset($res["title"]) || strlen($res["title"]) === 0) continue;
$url = "/contents/";
//日誌ページの場合
if($res["label_id"] == 2){
$url .= "diary";
//辞書ページの場合
}else{
$url .= "dictionary";
}
$html[] = "<li><a href=\"" . $url . "/article/" . $res["alias"] . "\">" . $res["title"] . "</a></li>";
}
$html[] = "</ul>";
}else{
$html[] = "<div>「" . $query . "」を含む記事はありませんでした。</div>";
}
echo implode("\n", $html);
今回のスクリプトで重要な箇所として、SOY CMSのブログは必ず一つラベルを指定する必要があり、ブログが二つだと、ラベルを二つ指定する必要があります。
それをWHERE句でINを使ってラベルIDを直接二つ分指定しています。
(京都農販さんでは日誌のラベルIDが2で、辞書のラベルIDが3)
記事をいくつか取得出来たら、記事に紐づいているラベルのIDを調べ、ラベルIDに従って記事のURLを組み立て、echoで表示します。
これで複数のブログを合わせての検索の機能ができた。
これがスクリプトモジュールブロックであると、SQLの実行結果の各記事の配列をEntryオブジェクトに変換した後に繰り返し処理が始まるため、表示直前で記事がどのブログに紐づいているかが分からず、適切なURLを出力することができませんでした。
一方、モジュールはなんでもありなので、わざわざEntryオブジェクトにせずとも、そのままechoで表示が可能なので、今回の様な仕様も簡単に実装できたわけだ。





