とあるサイトで検索機能を追加することになった。
前にもこのサイトで作ったじゃないか!というのは置いといて、
今回のケースでもまぁ聞いてくれ。
今回のサイトでは、
日誌のブログと辞書のブログの二つのブログページを運用している。
当然、検索した時も二つのブログページを合わせて結果一覧を出したいもの。
しかし、
前のスクリプトモジュールブロックだと何かと都合が悪い。
というわけで、
何でもできる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で表示が可能なので、
今回の様な仕様も簡単に実装できたわけだ。