MTプラグインを使わずにページングを実装する (Movable Type 6, 7)

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 を変更することで可能です。みなさんも是非お試し下さい。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ