MovableTypeのエントリー高速検索Widget
MovableTypeにデフォルトでついてる検索は遅い・・・
もう、これでもかって言うくらい遅い上に
動的に検索しているからサーバへの負荷も大きそうなのである。
で、ちと実験がてら作ってみた。
最初はMovableTypeのAPIいじってとか
考えてたけど、めんどくさくなったのと
サーバの負荷減らすために
クライアント側で処理させるようにした。
検索用のデータを投稿時に作って
それをjavascriptで検索するようにした。
正規表現とか使おうかとか
スペースで複数指定してAND検索とか
思ったけど
めんどくさいからそのまま素で検索。
半角の大文字小文字だけ丸めた
実験だし・・という名の言い訳。
で、インクリメンタルサーチにしてみた。
インクリメントサーチだったらAND検索とか無くてもいいかなぁって・・・
ついでにせっかくだしWidget化・・・
と言うわけで使い方。
まず、検索用のデータを作らなきゃいけないので
MovableTypeの管理画面で
「テンプレート」→ (「インデックス・テンプレート」→ )「テンプレートを新規作成」
- 「テンプレート名」は適当に入力(俺はENTRY_DATAにしました)
- 「出力ファイル名」にdata.jsと入力
- 「再構築オプション」にチェックを入れる
- 「このテンプレートにリンクするファイル」は何も入力しない
- 「テンプレートの内容」に下記コピペ
var data = [
<MTArchiveList><MTEntries>{
title:"<$MTEntryTitle remove_html="1" encode_js="1"$>",
link:"<$MTEntryLink$>",
body: "<$MTEntryTitle remove_html="1" encode_js="1"$><$MTEntryBody remove_html="1" encode_js="1"$><$MTEntryMore remove_html="1" encode_js="1"$>",
date:"<$MTEntryDate format="%Y/%B/%e %k:%M"$>"
}
<MTEntryPrevious>,</MTEntryPrevious>
</MTEntries></MTArchiveList>
];
これでデータは準備完了。
で、次にWidgetの作成。
同じように
MovableTypeの管理画面で
「テンプレート」→ 「テンプレート・モジュール」→「モジュールを新規作成」
- 「テンプレート名」は頭に「Widget: 」をつけて適当に(俺は「Widget: javascriptSearch」にしました)
- 「このテンプレートにリンクするファイル」は何も入力しない
- 「テンプレートの内容」に下記コピペ
<style>
#result{
border:solid 1px #666;
background: #1f2d3a;
text-align:left;
}
#result .item{
border:solid 1px #666;
}
#result .item a{
color:#f93;
}
#result .item .date{
text-align:right;
font-style: italic;
font-size:95%;
}
</style>
<script type="text/javascript" src="<$MTBlogURL$>data.js"></script>
<script type="text/javascript">
<!--
var resultElement = document.getElementById('result');
function search(queryElement){
var query = queryElement.value;
var naviElement = document.getElementById("navi");
if(!resultElement){
var div = document.createElement('div');
div.setAttribute('id', 'result');
div.style.position='absolute';
div.style.left=xPageX(queryElement)+"px";
div.style.top=xPageY(queryElement) + queryElement.offsetHeight+"px";
document.body.appendChild(div);
resultElement = div;
}
var result = "";
if(query.length == 0){
resultElement.innerHTML = "";
resultElement.style.visibility = "hidden";
naviElement.innerHTML="";
return;
}
var result = "";
var resultCount = 0;
for(var i=0;i<data.length;i++){
if(data[i].body.toUpperCase().indexOf(query.toUpperCase()) >= 0){
result +='<div class="item">';
result +='<a href="'+ data[i].link + '">';
result +='<div class="title">'+ data[i].title + "</div>";
result +='<div class="date">'+ data[i].date + "</div>";
result +='</a></div>';
naviElement.innerHTML=++resultCount + "/" + data.length;
}
}
resultElement.style.visibility = "visible";
resultElement.innerHTML = result;
}
function xPageX(e){
var x = 0;
while (e) {
if (xDef(e.offsetLeft)) x += e.offsetLeft;
e = xDef(e.offsetParent) ? e.offsetParent : null;
}
return x;
}
function xDef(){
for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
return true;
}
function xPageY(e){
var y = 0;
while (e) {
if (xDef(e.offsetTop)) y += e.offsetTop;
e = xDef(e.offsetParent) ? e.offsetParent : null;
}
return y;
}
//-->
</script>
<div class="module-search module">
<h2 class="module-header">検索</h2>
<div class="module-content">
<input type="text" onkeyup="search(this);" autocomplete="off" size="15"/><span id="navi"></span>
</div>
</div>
これでwidgetも準備完了。
最後に「WidgetManager」でさっき作ったWidgetを
使用するようにして再構築。
以上♪
あんまり記事数が多いと破綻するような仕組みだけど
そんなに記事数多いと
標準の検索の方が先に破綻しそうなので
気にしない方向で・・・
あ、ちなみにAjaxとか使ってないです(^^;
2006/08/26
続き・・・ちょっと修正↓
MovableTypeのエントリー高速検索WidgetとSafari

