Movable Type 4.2 の Ajax 検索機能
Movable Type 4.2 の検索機能ではページ分割が導入されました。
検索結果が複数のページに跨る場合(=ページ分割された場合)は、Google マップのスクロールのように、次の検索結果ページを Ajax で事前に取得します。
その結果、分割ページに移動するときは、ストレスのないページ送りができるようになっています。瞬時に前後ページに移動できるので、かなり快適です。
ただし、初回の検索は Ajax ではありません。
本エントリーでは、検索結果ページで使われている JavaScript をかなり簡単に紹介します。
1.getResults
MTIfMoreResultsタグで、検索結果がページ分割されている場合にこのコードがページに展開され、現在の検索結果の表示中にバックグラウンドで Ajax を起動し、次のページの検索結果を取得・保持します。
<MTIgnore>Below Javascript adds ajax search capability</MTIgnore>
<script type="text/javascript">
/* <![CDATA[ */
<MTIfMoreResults>
function getResults(page) {
page = parseInt(page);
if (timer) window.clearTimeout(timer);
var xh = mtGetXmlHttp();
if (!xh) return false;
var res = results[page];
if (!res) return;
var url = res['next_url'];
if (!url) return;
xh.open('GET', url + '&format=js', true);
xh.onreadystatechange = function() {
if ( xh.readyState == 4 ) {
if ( xh.status && ( xh.status != 200 ) ) {
// error - ignore
} else {
try {
var page_results = eval("(" + xh.responseText + ")");
if ( page_results['error'] == null )
results[page + 1] = page_results['result'];
} catch (e) {
}
}
}
};
xh.send(null);
}
...中略...
</MTIfMoreResults>
/* ]]> */
</script>
この関数は、検索結果ページに埋め込まれた次のスクリプトで実行されます。
<MTIgnore><!-- Used with the ajax search capability of the new search class --></MTIgnore>
<MTIfMoreResults>
<script type="text/javascript">
<!--
var div = document.getElementById('search-results');
var results = {
'<MTCurrentPage>': {
'content': div.innerHTML,
'next_url': '<MTNextLink>'
}
};
var timer = window.setTimeout("getResults(" + <MTCurrentPage> + ")", 1*1000);
//-->
</script>
</MTIfMoreResults>
次のページのURLは、getResults の内部処理で JSON 型の変数 results の next_url にアクセスし、MTNextLinkタグで展開された URL を取得します。
getResults は、周期処理を行うための window.setTimeout で起動され、getResults の内部処理の window.clearTimeout で周期処理を停止します。つまり1回しか起動されません。また、1秒周期で実行するため、検索結果が表示されてからすぐにリンクをクリックすると、Ajax による次のページ取得が完了していない場合があります。
2.swapContent
検索結果本文を、保持している前後の検索結果と置き換えます。
<script type="text/javascript">
/* <![CDATA[ */
<MTIfMoreResults>
...中略...
function swapContent(direction) {
if ( direction == undefined ) direction = 1;
var page_span = document.getElementById('current-page');
if (!page_span) return true;
var next_page = direction + parseInt(page_span.innerHTML);
var res = results[next_page];
if (!res) return true;
var content = res['content'];
if (!content) return true;
var div = document.getElementById('search-results');
if (!div) return true;
div.innerHTML = content;
timer = window.setTimeout("getResults(" + next_page + ")", 1*1000);
window.scroll(0, 0);
return false;
}
<MTElse><MTIfPreviousResults>
function swapContent(direction) {
return true;
}</MTIfPreviousResults>
</MTIfMoreResults>
/* ]]> */
</script>
この関数は、検索結果ページに埋め込まれたページ移動用のナビゲーションの「前」「次」のリンクから実行されます。
<MTIgnore><!-- Used with the ajax search capability of the new search class --></MTIgnore>
<div class="content-nav">
<MTIfPreviousResults>
<a href="<MTPreviousLink>" rel="prev" onclick="return swapContent(-1);">< 前</a>
</MTIfPreviousResults>
<MTPagerBlock>
<MTIfCurrentPage>
<MTVar name="__value__">
<MTElse>
<a href="<MTPagerLink>"><MTVar name="__value__"></a>
</MTIfCurrentPage>
<mt:unless name="__last__"> </mt:unless>
</MTPagerBlock>
<MTIfMoreResults> <a href="<MTNextLink>" rel="next" onclick="return swapContent();">次 ></a>
</MTIfMoreResults>
なお、Ajax によるページ移動は「前」「次」のリンクを使った場合のみ有効で、ページ番号のリンクをクリックしたときは通常のCGI起動になります。
3.注意事項
ページ分割時の Ajax を有効に活用するには、次の青色の1行が必要です。
...前略...
<MTSearchResults>
<MTSearchResultsHeader>
<div id="search-results">
<span id="current-page" class="hidden"><MTCurrentPage></span>
<h1 id="page-title" class="search-results-header">
...後略...
関数 swapContent の内部処理で、現在のページ番号をここから取得しています。
- フォルダアーカイブとフォルダアーカイブ一覧を作る
- MTEntriesWithSubCategories タグの不具合などについて
- Movable Type 4.1 と 4.2 の差分(コメント入力フォーム)
- Movable Type 4.2 テンプレートセット(フッタ付きリキッドレイアウト対応)
- アップロード画像の img 要素の alt 属性・title 属性をカスタマイズする
- 【重要】MT4.1x → MT4.2 へのアップグレード注意
- Movable Type 4.2 テンプレートセット(スタイル対応版)
- Movable Type 4.2 にアップグレード
- Movable Type 4.1x から 4.2 へのアップグレード
- Movable Type 4.2 日本語版リリース
- Movable Type 4.2 リリース
- Movable Type 4.2 リリース延期
- Movable Type(MT) 4.2 テンプレートセット
- Movable Type 4.2 リリース候補第4版公開
- MTDate タグ・モディファイア詳説
お忙しいところ、度々のサポート要請で申し訳ありません。
この記事を見て、小粋空間さんのテンプレート(4.2Styleタイプ)に4.21デフォルトの検索関連テンプレートを移植する形で作ってみました。
1.私の移植のやり方が悪いのか、4.21元々の問題なのか私には分りませんが、
分割されたページの「前、分割ページの番号、次」のリンクで&(アンパサンド)が実体参照文字になっておらずW3CのValidation Checkでエラーとなります。考えられる対処方法があればご指摘いただけないでしょうか。
2.分割されたページの2ページ目以降はテンプレートを経由しないで編集されているようですが、これが仕様なのでしょうか。ページ・カテゴリの場合にテンプレートでメタデータ内のカテゴリがリンク付きのフォルダー名になるのを持ち替える等しているのですが、これが反映されません。
よろしくお願いします。
>オークさん
こんにちは。
ご質問の件ですが、
1.mt:PreviousLink タグ・mt:PagerLink タグ・mt:NextLink タグに escape="html" というモディファイアを設定してみてはいかがでしょうか。
2.2ページ目以降は Ajax または ページ指定した検索用CGIを起動しているという認識です。文章の後半はご要望の内容が理解できませんでした。すいません。
それではよろしくお願い致します。
荒木さん、おはようございます。
1項につきましては、お蔭様で解決いたしました。アドバイスありがとうございます。
2項につきましては、2ページ目以降も1ページ目同様の記事の編集が出来ればと思った次第です。Ajaxと言うものを理解できていませんので、もう少し勉強してからにします。
度々のサポート、ありがとうございました。
>オークさん
こんにちは。
ご連絡ありがとうございました。
Ajax ではページの一部を入れ替えるだけなので、おそらく、カスタマイズしたい部分が2ページ目以降の入れ替え対象に含まれていない、と理解致しました。
つまり、2ページ目以降に何かを反映させるには、検索結果テンプレートの MTSearchResults タグのブロック内に書き込まないといけないと思います。
それではよろしくお願い致します。