とあるサイトで検索機能を追加することになった。

前にもこのサイトで作ったじゃないか!というのは置いといて、

今回のケースでもまぁ聞いてくれ。

検索フォームと検索結果ページを作ってみた1


今回のサイトでは、

日誌のブログと辞書のブログの二つのブログページを運用している。


当然、検索した時も二つのブログページを合わせて結果一覧を出したいもの。


しかし、

前のスクリプトモジュールブロックだと何かと都合が悪い。


というわけで、

何でもできるcms:moduleで検索結果ページを作ってみた。

SOY CMSでどのページでも使えるブログのサイドバーを作ってみた




はじめに、


kyonou_search_module


管理画面のモジュール管理でモジュールを作成します。

この時作成するのはPHPの記述ができる方です。


ここで作成したモジュールのタグを、


kyonou_search_result

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で表示が可能なので、

今回の様な仕様も簡単に実装できたわけだ。