MovableTypeのSearchをAjaxでやってみる
とりあえず、実装の仕方をまとめてみました。変なとこあったら言ってください。
基本的には、$MT_HOME/search_template/default.tmpl のコピーを下記の名前で保存。
$MT_HOME/search_template/ajax.tmpl
$MT_HOME/search_template/result.tmpl
ajax.tmplにはAjaxでのコードを書き(後述)、result.tmplにはヘッダーとかフッターを除いた検索結果を出すように体裁を整えます。
また、これらをテンプレートとして使えるように $MT_HOME/mt.cfg の中身に下記を追加しました。
AltTemplate ajax ajax.tmpl AltTemplate result result.tmplこうすることにより、検索ページのテンプレートを http://example.com/mt-search.cgi?IncludeBlogs=1&Template=ajax として、Templateというクエリに指定して使用することができるようになります。 ajax.tmplの中身は、下記のようになってます。
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=<$MTPublishCharset$>" />
6 <meta name="generator" content="http://www.movabletype.org/" />
7
8 <title><MT_TRANS phrase="Search Results"></title>
9 <link rel="stylesheet" href="<$MTBlogURL$>styles-site.css" type="text/css" />
10 <script language="JavaScript" type="text/javascript" src="xmlhttprequest.js"></script>
11 <script language="JavaScript" type="text/javascript">
12 <!---
13 function doSearch() {
14 var http = new XMLHttpRequest();
15 if (http) {
16 http.onreadystatechange = function(){
17 var result = document.getElementById('result');
18 result.innerHTML = '<img src="progress.gif" />';
19 if (http.readyState == 4 && http.status == 200) {
20 removeresult();
21 result.innerHTML = http.responseText;
22 }
23 };
24 var q = document.getElementById('q');
25 http.open('GET', 'http://clouder.jp/mt/mt-search.cgi?IncludeBlogs=<$MTBlogID$>&Template=result&search=' + q.value);
26 http.send(null);
27 }
28 }
29 function removeresult() {
30 var result = document.getElementById('result');
31 result.innerHTML = "";
32 }
33 //--->
34 </script>
35 </head>
36
37 <body>
38
39 <div id="banner">
40 <a href="<$MTBlogURL$>" accesskey="1"><$MTBlogName$></a>
41 <span class="description"><$MTBlogDescription$></span>
42 </div>
43
44 <div class="content">
45
46 <div class="blog">
47
48 <form method="post" action="<$MTCGIPath$><$MTSearchScript$>" onsubmit="doSearch(); return false;">
49 <input type="hidden" name="IncludeBlogs" value="<$MTBlogID$>">
50
51 <div class="blogtitle"><MT_TRANS phrase="Search this site:"></div>
52
53 <div class="blogbody">
54 <p><input type="text" size="30" name="search" value="<$MTSearchString$>" id="q" /> <input type="button" value="<MT_TRANS phrase="Search">" onClick="doSearch();" /></p>
55
56 </form>
57 </div>
58
59 <div id="result">
60 </div>
61 </div>
62
63 </div>
64
65 </body>
66 </html>
また、result.tmplに関してはヘッダーやフッターを適当取って、検索結果だけを表示するようにしておいてください。次に、以前紹介したサイトからxmlhttprequest.jsを取ってきて、それを適当なディレクトリに置いて10行目のように読み込みます。
そして11行目から34行目の間にようにjavascriptを記述します。
このjavascriptには2つの関数が書かれています。doSearch()という関数は検索のリクエストを投げる関数。removerequest()という関数は表示された検索結果を一旦削除する関数になります。
doSearch()の中では、http という変数に XMLHttpRequestオブジェクトのインスタンスを入れて、http.open()で、FORMタグで言うところの「method」と「action」を指定して、http.send()によってリクエストを飛ばしています。actionの指定するURLは「http://example.com/mt-search.cgi?IncludeBlogs=<$MTBlogID$>&Template=result&search=検索文字列」となります。
http.onreadystatechange というのに、無名の関数を代入していますが、これは http.send() で飛ばした際のハンドラになります。http.send()したあとのリクエストのフェーズ毎にこの関数が呼ばれるようです。
フェーズの数字については、
0 = uninitialized
1 = loading
2 = loaded
3 = interactive
4 = complete
このようになっているようです。
そして、結果が帰ってきて http.readyStateが4(complete)になったときには、idがresultというdivタグで囲まれた空白の部分が59行目付近に用意してありますので、そちらに innnerHTML を使って結果を貼り付けています。
ちなみに18行目のinnerHTMLは、プログレスバーを表示しているだけで、結果を表示する際には一旦 removeresult()が呼ばれて消されるようになっています。
こうやって使ってみると、もっと他の使い方がいろいろできそうだなと思いました。
これだけだとすごくつまらない使い方しかしてない気になってきた…。
また時間をみつけてなにかやってみようと思います。