【MovableType】一定数の記事ごとにページを分割する


MT には最近のバージョン(4.3 以降?)からページ送り機能がついている。これは長すぎるページを一定間隔に区切って分け、各ページにリンクを付けてくれる機能だ。Google の検索結果の一番下に出てくる「1 2 3 4 5 »」のような表示と考えればわかりやすい。特に月別やカテゴリー別のページは数百個の記事が並ぶこともあるわけで、記事が多くなったら必ず導入しておきたい。……というか、なんで標準のテーマにこれがないのかね?

小粋空間: Movable Type 4.3 の新機能(スタティックページのページ分割)
http://www.koikikukan.com/archives/2009/07/29-005555.php

主に、上のリンクに従って設定した。以下に手順を書いていく。

テンプレートモジュールの新規作成

上のリンクにあるとおり、2 つのテンプレートモジュールを作成する。 URL 中の「&」がエンコードされずにそのまま入るようになっていたので、encode_html="1" を足しました。

<mt:If name="search_results">
<div class="content-nav">
    <mt:IfPreviousResults><a href="<$mt:PreviousLink encode_html="1"$>" rel="prev" onclick="return swapContent(-1);">< Previous</a>  </mt:IfPreviousResults><mt:PagerBlock><mt:IfCurrentPage><$mt:Var name="__value__"$><mt:Else><a href="<$mt:PagerLink encode_html="1"$>"><$mt:Var name="__value__"$></a></mt:IfCurrentPage><mt:Unless name="__last__"> </mt:Unless></mt:PagerBlock><mt:IfMoreResults>  <a href="<$mt:NextLink encode_html="1"$>" rel="next" onclick="return swapContent();">Next ></a></mt:IfMoreResults>
</div>
<mt:Else>
    <mt:If name="main_index">
        <mt:BlogEntryCount setvar="total_entries">
    <mt:Else>
        <mt:ArchiveCount setvar="total_entries">
    </mt:If>
    <mt:If name="total_entries" gt="$entries_per_page">
        <mt:Ignore>Set the total number of entries to iterate through the pages</mt:Ignore>
        <mt:If name="total_entries" op="%" value="$entries_per_page" eq="0">
            <mt:Var name="total_entries" op="/" value="$entries_per_page" setvar="total_pages">
        <mt:Else>
            <mt:Var name="total_entries" op="%" value="$entries_per_page" setvar="remainder">
            <mt:Var name="total_entries" op="-" value="$remainder" setvar="total_pages">
            <mt:SetVar name="total_pages" op="/" value="$entries_per_page">
            <mt:SetVar name="total_pages" op="++">
        </mt:If>
 
        <div class="content-nav">
            <mt:For from="1" to="$total_pages" step="1">
            <mt:If name="__first__">
                <$mt:Var name="__index__"$>
            <mt:Else>
                <a href="<mt:Var name="search_link" strip_linefeeds="1" trim="1" encode_html="1"><$mt:Var name="__index__"$>"><$mt:Var name="__index__"$></a>
            </mt:If> 
            </mt:For>
            <a href="<mt:Var name="search_link" strip_linefeeds="1" trim="1" encode_html="1">2" rel="next">Next »</a>
        </div>
    </mt:If>
</mt:If>
<mt:Ignore>Use the entries_per_page variable to set the number of entries per page</mt:Ignore>
<mt:Var name="entries_per_page" value="10">
<mt:SetVarBlock name="search_link">
    <mt:If name="main_index">
        <mt:SetVarBlock name="index_string">&archive_type=Index</mt:SetVarBlock>
    </mt:If>
    <mt:If name="archive_template">
        <mt:SetVarBlock name="archive_string">&archive_type=<mt:ArchiveType></mt:SetVarBlock>
        <mt:If name="datebased_archive">
            <mt:SetVarBlock name="date_string">&year=<mt:ArchiveDate format='%Y'>&month=<mt:ArchiveDate format='%m'>&day=<mt:ArchiveDate format='%d'></mt:SetVarBlock>
        </mt:If>
        <mt:If name="category_archive">
            <mt:SetVarBlock name="category_string">&category=<mt:CategoryID></mt:SetVarBlock>
        </mt:If>
        <mt:If name="author_archive">
            <mt:SetVarBlock name="author_string">&author=<mt:AuthorID></mt:SetVarBlock>
        </mt:If>
    </mt:If>
    <mt:CGIPath><mt:SearchScript>?IncludeBlogs=<mt:BlogID>&template_id=<mt:Var name="template_id">&limit=<mt:Var name="entries_per_page"><mt:Var name="index_string"><mt:Var name="date_string"><mt:Var name="category_string"><mt:Var name="author_string"><mt:Var name="archive_string">&page=
</mt:SetVarBlock>

2 行目にある value="10" というのが、1 ページに載せる記事の数になる。必要ならば変更しよう。

インデックステンプレート・アーカイブテンプレートの編集

どちらもやることは変わらないのでまとめて書く。インデックステンプレートというのはトップページ、つまり、index.html を作成するためのもので、アーカイブテンプレートというのは月別・カテゴリー別に記事を分けたページに相当する。

設定情報を挿入する

テンプレート内に以下のコードを追加する。参考リンクでは共通ヘッダーの直後に置くこととしているが、特に場所は厳密ではないようだ。

<mt:BuildTemplateID setvar="template_id">
<$mt:Include module="Search Header Data"$>

記事表示部分を改変する

記事の最上部と最下部にリンク(「Prev 1 2 3 4 Next」のようなもの)を挿入する。記事の表示ルーチン自体もちょっとだけ変更。ここは各々が使っているテーマによって異なると思うので、以下のはあくまでも例である。

このサイトで使っている mt.Vicuna テーマでは記事の表示部分が次のようになっている。

<mt:Entries>
<$mt:EntryTrackbackData$>
<$mt:Include module="エントリー概要"$>
</mt:Entries>

これを以下のように改変した。

<$mt:Include module="Search Pagination"$>
<mt:Entries limit="$entries_per_page" search_results="1">
<$mt:EntryTrackbackData$>
<$mt:Include module="エントリー概要"$>
</mt:Entries>
<$mt:Include module="Search Pagination"$>

ハイライトした部分が変更点である。参考リンクでは search_results="1" の部分が抜けていたので少し混乱した。

スタイルシートの設定

これはおまけだが、スタイルシートを設定して見栄えを良くしておこう。これこそサイトによって千差万別なので、一つの例として挙げておく。

/* Search Pagination */
div.content-nav {
    font-size: 114%;
    padding: 0.2em;
    margin: 1em 12.5% !important;
    text-align: center;
    color: #086dac;
    background-color: #ebf1f2;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

以上で設定は完了だ。うまく行ったら次のように各ページへのリンクが貼られているだろう。

100812-0001.png

不具合への対応

100811-0001.png

標準以外のテーマを使っていたりすると、2 ページ目以降のリンクをクリックしたときに「テンプレートはインデックスでないアーカイブタイプ用の記事リストidを持たなければなりません」というエラーが出て正常に作動しないことがある(右図参照)。これはテンプレートの属性が間違っているために(?)起こるものなので、データベースを直に書き換えて直してしまおう。

Movable Type 5β4でのページ送りの不具合と修正 – The blog of H.Fujimoto
http://www.h-fj.com/blog/archives/2009/10/26-113417.php

修正するには問題が起こったテンプレートの ID を特定しないといけない。テンプレート編集画面を開いたときその URL が以下のものだったとする。

http://www.example.com/mt/mt.cgi?__mode=view&_type=template&id=1234&blog_id=99

この中の“1234”が ID だ。この ID をメモしておいて mysql にログインする1

mysql>
$ /usr/local/mysql/bin/mysql -uroot -p mt
Enter password:

mysql> select template_identifier from mt_template where template_id = 1234;
+------------------------+
| template_identifier    |
+------------------------+
| entry_listing_category |
+------------------------+
1 row in set (0.00 sec)

mysql>

ページ送りのためには template_identifier~entry_listing の形式になっている必要がある。mysql コマンド上から次の SQL 文を実行しよう。

mysql> update mt_template set template_identifier = 'category_entry_listing' where template_id = 1234;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>

月別アーカイブテンプレートでは template_identifierentry_listing_databased となっていたので、同様にして databased_entry_listing に書き換えた。

mysql> select template_identifier from mt_template where template_id = 2345;
+-------------------------+
| template_identifier     |
+-------------------------+
| entry_listing_databased |
+-------------------------+
1 row in set (0.00 sec)

mysql> update mt_template set template_identifier = 'databased_entry_listing' where template_id = 2345;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>

  1. 参考リンクでは phpMyAdmin が推奨されているが、今回は面倒なので全部 mysql コマンドで処理してしまった。 

One thought on “【MovableType】一定数の記事ごとにページを分割する

  1. Pingback: MTテンプレートキングのトップページで次ページ処理をする方法| 八木ラボ

コメントを残す