サイトリニューアルにあたり、サイト内検索システムを今まで使用していた 「Google Custom Search Engine」 から以前紹介した、「MT 向け Ajax サイト内検索」 に変更しました。
Google Custom Search Engine 自体は良かったのですが、検索結果表示のサイズが、横幅 500px 以下にならないという制約から、新しいデザインではちょっと収まりが悪かったため、今回の変更に至ったわけです。
ただ、この Ajax サイト内検索は、動作が JavaScript によって行われるため、JavaScript が無効な状態だとサイト内検索がまったく使えない状態になるというのが難点。そこで今回は JavaScript が無効な場合でも不便にならないよう一工夫してみることに。
で、どうするかというと、JavaScript が有効な状態では、Ajax サイト内検索に、JavaScript が無効になっている場合には、Movable Type 標準の mt-search.cgi に検索クエリを投げるようにすればいいわけです。
これを実現するためのひとつの方法としては、Ajax サイト内検索用のフォーム部分を JavaScript で書き出してあげて、JavaScript 無効時用のフォームを noscript 要素で書いておいてあげるという手がありますが、今回はもっと少ない手間で、さらにソースも煩雑にならない方法を試してみました。
ではまず最初にサイト内検索フォームの改造から。ノーマルの Ajax サイト内検索 (詳しくはこちらで) では、フォーム部分のソースは下記のようになっています。(当サイトの検索フォームとはすこし違います。)
<form action="javascript:blogAjaxJsonSearch( '<$MTBlogURL$>search_data.txt',document.getElementById('search_box').value );"> <fieldset> <legend accesskey="s">サイト内検索</legend> <p> <input type="text" name="search_box" id="search_box" value="Site Search" onfocus="initialize(this)" /> <input type="button" value="search" onclick="javascript:blogAjaxJsonSearch( '<$MTBlogURL$>search_data.txt', document.getElementById('search_box').value );" onkeypress="javascript:blogAjaxJsonSearch( '<$MTBlogURL$>search_data.txt', document.getElementById('search_box').value );" /> </p> <p> <input type="checkbox" checked="checked" name="ASuseReadCache" id="ASuseReadCache" /> <label for="ASuseReadCache">キャッシュ使用</label> </p> <p class="powered_by"> Powered by <a href="http://java.cocolog-nifty.com/blog/" title="暴想">暴想</a> </p> </fieldset> </form>
これを、下記のように変更します。変更点は、
- form 要素の action 属性値を mt-search.cgi のパスに書き換える
- id 属性と method 属性を追加
- input 要素の type="button" を type="submit" に変更
- 必要に応じて mt-search.cgi での検索用に隠しパラメータを追加
<form id="site_search" action="<$MTCGIPath$><$MTSearchScript$>" method="post"> <fieldset> <legend accesskey="s">サイト内検索</legend> <input type="hidden" name="IncludeBlogs" value="<$MTBlogID$>" /> <p> <input type="text" name="search_box" id="search_box" value="Site Search" onfocus="initialize(this)" /> <input type="submit" value="search" onclick="javascript:blogAjaxJsonSearch( '<$MTBlogURL$>search_data.txt', document.getElementById('search_box').value );" onkeypress="javascript:blogAjaxJsonSearch( '<$MTBlogURL$>search_data.txt', document.getElementById('search_box').value );" /> </p> ...略... </fieldset> </form>
これでフォーム部分の修正は完了。ただ、このままだと検索クエリはすべて mt-search.cgi に行ってしまうので、最後に JavaScript が有効な時は form 要素の action 属性に入る URI を元の JavaScript スキームにしてあげる必要があります。そこで、blog_ajax_json_search.js の最後に下記のソースを追加します。
function SearchForm() { var form = document.getElementById('site_search'); form.action = "javascript:blogAjaxJsonSearch( 'path_to/search_data.txt',document.getElementById('search_box').value );"; } Event.observe(window, 'load', SearchForm, false);
「path_to/search_data.txt」 の path_to はsearch_data.txt までのパスを入れてください。
要はページ読み込み完了時に、JavaScript によって form 要素の action 属性を書き換えてやるという作戦ですね。
これで予定通り、JavaScript が有効な時は Ajax サイト内検索が、無効なら mt-search.cgi が動作するというわけ。ページの読み込みが遅い場合など、検索実行のタイミングによっては mt-search.cgi にクエリが行ってしまう場合もありますが、その辺は上記関数の実行タイミングである程度は調整できます。