昨日は、MTなごやで毎月実施している『Movable Typeの日』。たまたま、カスタマイズでつまずいている部分を相談できた。
Movable Typeをカスタマイズしていくとき、できるだけ余分なプラグインは使わないようにしたいところ。
記事の一覧ページなどで、複数ページに分割するときなど「PageButeプラグイン」が有名。しかし、できれば標準機能でページ分割を行いたい。MT5.2から加わった「Rainier」テーマに含まれる「ページネーション」の仕組みなどをよく使う。
しかし、今回デザインをもらった案件がこのようなページ分割のナビゲーション。
さすがに、標準機能だけでは厳しいかなと。「PageButeプラグイン」を使わせていただくことにした。
PageButeプラグイン
PageButeプラグインは、Movable Typeで生成するページを、指定した記事数でページ分割してくれるもの。かなり前から公開されているプラグインで、利用者も多いはず。ページの分割を動的に行うのではなく、静的ページとして生成してくれるので、Movable Typeの良さを活かすことができる。
記事を分割したい部分(<MTEntries>
など)を<MTPageContents></MTPageContents>
で括り、<MTPageLists>
でページ番号を出力できるわけだが、バージョン3.5.4以降では、<MTPageLists>
の替わりに<MTPagination></MTPagination>
を使うことで、ナビゲーション部分を細かくカスタマイズできるらしい。これなら大丈夫ではないかと。
さて、デザインのナビゲーション部分はすんなりできた。困ったのはページ毎に表示される「11件 - 20件」というような部分だ。3ページ目だと「21件 - 30件」最後のページは「31件 - 32件」のような感じだ。このような出力は「PageButeプラグイン」でも用意されていないようだ。
とはいえ、<MTPageCount>
で現在のページ番号を出力できる。ページ番号から1を引いて、10をかけて1を足したのを始めの件数として、それに9を足したのを終わりの件数。最後のページだけは、総件数を終わりにすれば良い。たぶん、もっとスマートな方法もあるだろうけど、まあできそうだ。
ページ数に計算ができない罠
MTタグで計算する方法は、下記のページなどを参照。足したり掛けたりを1行づつ書かなきゃいけないが、できそうだ。
Movable Type のテンプレートには、四則演算を行うためのモディファイアがあります。これらのモディファイアを使うと、「足す、引く、割る、掛ける」といった計算を、テンプレートタグだけで行うことができます。
こんな感じかなと。
<mt:SetVarBlock name="all_count"><$mt:EntriesCount$></mt:SetVarBlock>
<$mt:PageCount setver="start_count"$>
<$mt:SetVar name="start_count" value="1" op="-"$>
<$mt:SetVar name="start_count" value="10" op="*"$>
<$mt:SetVar name="start_count" value="1" op="+"$>
<$mt:GetVar name="all_count"$>件中 <$mt:GetVar name="start_count"$>件 - <$mt:GetVar name="all_count"$>件
本当は、これに最後のページかの判別も加えるわけだが、一旦ここまで。動くものと思ったら動かない。どうも<$mt:PageCount>
はちゃんと出力されているのだが、それが変数に入って計算ができていない。どういうことかと。
ここで『Movable Typeの日』に突入。そこで参加いただいていたWebbingStudio(ウェビングスタジオ)のうぇびんさんんからアドバイス。「PageButeの仕様上、検索ページとかでも使えないし、条件分岐や計算もできないはず」と。
検索ページは見た気がするが、条件分岐や計算もできないと??
その後も調べると、どうも通常のMTタグの処理が終わった後に、PageButeの処理が行われるっぽい。なので、条件分岐や計算の処理が終わった後にPageButeの処理が行われるので、出力されたページ数はそのままなのだ。なんたる罠。
無理やりMTタグで計算してしまう
うぇびんさんからは、ダイナミックテンプレートを使うか、jQueryでやったほうが早いと助言。しかし、プログラムとか得意じゃないし、できたら静的ページで処理したいなと諦めきれずにいるとこんな記事が。
【MTページ分割】各ページに「全xx件中 x件?x件」と表示させる?|?システム開発ブログ(システム開発のアイロベックス|東京都新宿区の業務システム開発会社)
同じようなことを考える人がいる。そして、実現できてるようだ。そうだよね、PageButeのタグに頼らずにMTタグで計算しちゃえば良いんだよね。
と思い参考にしつつ見てみると2度目の罠。参考サイトは、<MTEntries>
内にページ分割を表示している。しかも、記事一覧の頭に表示しているようだ。
しかし、今回のデザインでは、ページネーションは<MTEntries>
の外にしていた。そして、一覧の下に表示。
ここで、プログラムができる人は簡単にやっちゃうんだろうなと羨みつつ、なんだかいろいろと試行錯誤してできたのが下記。少し省略しつつも下記のように実装して思い通りになりましたとさ。
一応、何件区切りにするかも変更できるようにしてある。ううむ。jQueryの本はiPadに入ってるんだがな。なんでもMTタグでやろうとしてしまう。
<mt:Ignore>初期設定</mt:Ignore>
<$mt:Var name="entries_per_page" value="10"$>
<$mt:Var name="entries_count" value="1"$>
<$mt:SetVar name="start_count" value="1"$>
<section>
<div id="news">
<ul>
<mt:PageContents count="$entries_per_page">
<mt:Entries lastn="1000">
<mt:SetVarBlock name="all_count"><$mt:EntriesCount$></mt:SetVarBlock>
<li><$mt:EntryDate format="%Y年%m月%d日"$><a href="<$mt:EntryPermalink$>"><$mt:EntryTitle$></a></li>
<mt:Ignore>ページ区切りだった場合の処理</mt:Ignore>
<mt:If name="entries_count" op="%" value="$entries_per_page" eq="0">
<mt:SetVarBlock name="current_count">
<$mt:GetVar name="start_count"$>件 - <$mt:GetVar name="entries_count"$>件
</mt:SetVarBlock>
</ul>
</div>
<!--newsBox-->
<div id="pager">
<p><$mt:GetVar name="all_count"$>件中 <$mt:GetVar name="current_count"$></p>
<mt:SetVar name="start_count" op="+" value="$entries_per_page">
<mt:Ignore>最後のページだった場合の処理</mt:Ignore>
<mt:Else>
<mt:If name="entries_count" eq="$all_count">
<mt:SetVarBlock name="current_count">
<$mt:GetVar name="start_count"$>件 - <$mt:GetVar name="all_count"$>件
</mt:SetVarBlock>
</ul>
</div>
<!--newsBox-->
<div id="pager">
<p><$mt:GetVar name="all_count"$>件中 <$mt:GetVar name="current_count"$></p>
</mt:If>
</mt:If>
<mt:Ignore>どっちでもなかった場合</mt:Ignore>
<mt:SetVar name="entries_count" op="++">
<$mt:PageSeparator$>
</mt:Entries>
</mt:PageContents>
<mt:Ignore>ページネーションの記述</mt:Ignore>
<mt:Pagination>
<mt:PaginationHeader>
<div>
<div>
<mt:IfPaginationPrev><p><a href="<$mt:PaginationPrev$>">前へ</a></p></mt:IfPaginationPrev>
<ul>
</mt:PaginationHeader>
<mt:IfPaginationCurrent>
<li class="cr"><mt:PaginationLink element="number"></li>
<mt:Else>
<li><a href="<$mt:PaginationLink$>"><$mt:PaginationLink element="number"$></a></li>
</mt:IfPaginationCurrent>
<mt:PaginationFooter>
</ul>
<mt:IfPaginationNext><p><a href="<$mt:PaginationNext$>">次へ</a></p></mt:IfPaginationNext>
</div>
</div>
</mt:PaginationFooter>
</mt:Pagination>
</div>
<!--pager-->
</section>
以下は簡単な解説。
最初のentries_per_page
で何件でページを別けるかを設定。ここでは10件にしている。
entries_count
とstart_count
を初期値1に設定。
<mt:Entries>
はとりあえず1000件表示にしてある。Pagebuteプラグインの場合、件数を表示した上であとで分割してるっぽい。
総記事数をは<$mt:EntriesCount$>
で取得して、all_count
に代入。
記事タイトルを表示した上で、現在のentries_count
をentries_per_page
で割ることで、余りが0だったらこのページの最後と判断。start_count
から現在のentries_count
までを表示してますよと表記する。
そして、次のページ用にstart_count
にentries_per_page
を足しておく。
ただ、このままだと最後のページがおかしくなるので、現在のentries_count
が総記事数と同じときも同じ処理を行うようにする。この場合はstart_count
にentries_per_page
を足す必要はない。
どちらでもない場合は、現在のページ数entries_count
に1を足して繰り返す。
この一連の後に、ページネーションの記述をしている。
<mt:Entries>
の中に、無理やりこの処理を入れてるのでややこしくなってしまっているが、デザインによってはもっと簡単になるはず。たぶん。