MTプラグインを使わずにページングを実装する (Movable Type 6, 7)
どうもfujiharaです。
梅雨っぽいですね。
本日は Movable Type でMTプラグインを使わずにページング機能を実装する方法をご紹介します。
背景
Movable Type 7 が出ましたね。弊社の案件で更新作業があったのですが、よく使われるPageButeがまだ 対応していないことがわかっておりました(Movable Type 7 RC リリースのお知らせと、正式リリース日のご案内)ので 今回実装を考えました。
仕様
以下の方針で実装しました。
- インデックステンプレートに記事用のjsonを登録する
- アーカイブページは1ページ出力のみ(カテゴリー、年月)
- アーカイブページでjson を取得して、記事をフィルタリングする。
- クエリーでページを指定
- ページング表示は外部 jQueryプラグインを使用
インデックステンプレート
インデックステンプレートは記事のタイトル、日付、リンク、各アーカイブをフィルタリングするようの値にしています。今回はテンプレート名はentries.jsonにしています。
[<mt:Entries lastn="0">{
"link":"<$mt:EntryPermalink$>",
"title":"<$mt:EntryTitle encode_json="1"$>",
"date":"<$mt:EntryDate format="%Y.%m.%d"$>",
"year_month":"<$MTEntryDate format="%Y/%m/"$>",
"category":"<mt:EntryCategories glue=","><$mt:CategoryLabel$></mt:EntryCategories>"
}<mt:EntriesFooter><mt:Else>,</mt:EntriesFooter></mt:Entries>]
アーカイブページ
各テンプレートで list に data-json で記事json のパス、 data-type はフィルター時のアーカイブタイプ、 data-filter はフィルターする文字列を出力しています。
** 年月用
<ol id="js-lists" data-json="<mt:BlogURL>entries.json" data-type="year_month" data-filter="<mt:ArchiveLink replace="$blog_url","">">
</ol>
<div id="pager"></div>
**カテゴリー用
<ol id="js-lists" data-json="<mt:BlogURL>entries.json" data-type="category" data-filter="<mt:CategoryBasename>">
</ol>
<div id="pager"></div>
Javascript , json取得, フィルタリング, ページングで記事指定
$(function () {
var $lists = $('#js-lists')
, $pager = $('#pager')
, json = $lists.data('json')
, filter = $lists.data('filter')
, type = $lists.data('type')
//1ページの表示数
, limit = $lists.data('limit') || 3
//現在のページをクエリーから取得
, page = getParameterByName('p') || 1
, allPage = 1;
page = parseInt(page),
//記事取得
$.ajax({
cache: false,
dataType: 'json',
url: json
}).done(function (data) {
//記事の挿入処理
insertData(data);
});
function insertData(entries) {
//フィルターとタイプがある場合はフィルタリング
if (type && filter) {
entries = entryFilter(entries);
}
//すべてのページ数を決定
allPage = parseInt(entries.length / limit);
if (entries.length % limit !== 0) {
allPage++;
}
var $li, $link;
//すべての記事から表示するようだけをフィルタリング
var index = limit * (page - 1);
//ページ数から取得するindex を指定
// ul に 挿入 render部分
// for loop まとめ
for (var i = index; i < index + limit; i++) {
if (!entries[i]) {
continue;
}
$li = $('<li>');
$link = $('<a>', {href: entries[i].link}).text(entries[i].title);
$link.appendTo($li);
$li.appendTo($lists);
}
//ページリンクを作成 (外部プラグイン)
$pager.twbsPagination({
totalPages: allPage,
startPage: page,
visiblePages: 5,
initiateStartPageClick: false,
onPageClick: function (event, page) {
location.href = location.pathname + '?p=' + page;
return false;
}
});
}
//フィルター用関数
function entryFilter(entries) {
switch (type) {
//カテゴリーの場合は json の category の値から
//登録されているcategory の , つなぎを配列にしフィルタリング
case 'category':
entries = entries.filter(function (entry) {
return entry.category.split(',').indexOf(filter) !== -1;
});
break;
//年別の場合は year_month キーでフィルタリング /yyyy/mm/ の形式
case 'year_month':
entries = entries.filter(function (entry) {
return entry.year_month === filter;
});
break;
}
return entries;
}
//query 取得関数
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
});
参考
クエリー取得関数
jQuery ページャープラグイン(jquery)
まとめ
いかがでしたでしょうか?これでPageButeを使わずに、 /archive_path/?p=x という形で
ページングを実装することができます。
記事更新時にはjson のみ更新されるので、再構築の時間が早いです。また、配信サーバでも使用することが可能です。
今回はjavascriptでフィルターしていますが、出力するjson を分けることでフィルタリングをMovable Type側にも吸収することが可能です。
json の指定は <ul> の data-json を変更することで可能です。みなさんも是非お試し下さい。