昨日、当ブログの読者の方から、Movable Typeに関するご質問をいただきました。
それを元に、「ブログ記事の公開日ごとに連番を振る」というカスタマイズを紹介します。
なお、このカスタマイズはMovable Type 4.1以降で利用できます。
1.ご質問の概要
いただいたご質問の概要は、以下のようなものです。
ブログ記事を一覧表示する際に、個々の記事の日付の箇所に、その公開日の中での連番を振りたいです。
ただし、その日に記事が1つしかない場合は、連番を振らないようにします。例えば、以下のように記事を書いたとします。
日付 記事数 2008年1月1日 1 2008年1月2日 3 2008年1月3日 1 2008年1月4日 2 この場合、各記事の日付の部分を以下のようにしたいです。
- 2008年1月1日
- 2008年1月2日-1
- 2008年1月2日-2
- 2008年1月2日-3
- 2008年1月3日
- 2008年1月4日-1
- 2008年1月4日-2
上記のようなことを正確に処理するには、同一公開日の記事の中での連番を求めるようなプラグインを作ることが必要です。
ただ、メインページに限定するなら、テンプレートタグだけでも何とかなります。
2.公開日ごとの記事数を数える
いただいたご質問では、同じ公開日の記事が2つ以上あるかどうかで、連番を振るかどうかを分けています。
そのような処理をするためには、同じ公開日の記事の数を調べることが必要です。
Movable Typeのタグにはそのようなものはありませんが、テンプレートタグを組み合わせて処理することができます。
MTEntriesタグを使うと、記事を順に取り出してその情報を扱うことができます。
このタグのブロックの中で、記事の公開日をキーとし、記事数を値とするハッシュを作るように、テンプレートタグを組みます。
例にあげたような場合だと、以下のようなハッシュを作るようにします。
| キー | 値 |
|---|---|
| 20080101 | 1 |
| 20080102 | 3 |
| 20080103 | 1 |
| 20080104 | 2 |
具体的には、以下のような流れで処理をします。
- 記事の公開日から、キーの値を求めます。
- 同じ公開日の中での最初の記事なら、そのキーに対応する値を1に初期化します。
- 同じ公開日の中での2つ目以降の記事なら、キーに対応する値を1増やします。
同じ公開日の中での最初の記事かどうかは、MTDateHeaderタグで判断することができます。
また、キーに対応する値をセットするのは、MTSetVarタグで行うことができます。
上記の処理を実際にタグで表すと、以下のようになります。
記事一覧を出力する部分(通常のMTEntriesタグのブロック)の前に、このタグを入れます。
<MTEntries>
<MTSetVarBlock name="day_key"><$MTEntryDate format="%Y%m%d"></MTSetVarBlock>
<MTDateHeader>
<MTSetVar name="day_count" key="$day_key" value="1">
<MTElse>
<MTSetVar name="day_count" key="$day_key" op="++">
</MTDateHeader>
</MTEntries>
3.連番を出力する
次に、記事一覧を出力する部分に手を加えて、連番を出力するようにします。
まず、同じ公開日の中で最初の記事のときには、連番を1に初期化し、また日付に対応するキーを作ります。
同じ公開日の中で最初の記事かどうかは、前述したMTDateHeaderタグで行うことができます。
連番を「ctr」という変数で管理するとすれば、この処理は以下のように書くことができます。
<MTDateHeader> <MTSetVarBlock name="day_key"><$MTEntryDate format="%Y%m%d"></MTSetVarBlock> <MTSetVar name="ctr" value="1"> </MTDateHeader>
また、日付を出力する部分では、以下のような処理をします。
- その記事と同じ公開日の記事が2個以上あるかどうかを判断する
- 2個以上あれば、ハイフンと連番(変数ctrの値)を出力し、次の記事の連番を出力するために、連番の値を1つ増やす
公開日ごとの記事の数は、「2.公開日ごとの記事数を数える」のところで作ったハッシュに保存されています。
そこで、そのハッシュから日付のキーに対応する値を得て、それが2以上かどうかを判断し、処理を分けます。
テンプレートタグで書くと、以下のようになります。
<MTIf name="day_count" key="$day_key" ge="2"> -<MTGetVar name="ctr"> <MTSetVar name="ctr" op="++"> </MTIf>
4.連番を逆順にする
Movable Typeの標準の設定では、記事は新しいものから順に出力されます。
上の手順で記事に連番を振ると、新しい記事から連番がつきます。
しかし、同じ日の記事の中では、古いものから連番を振りたいということも考えられます。
その場合、同じ日の最初の記事で、連番の初期値をその日の記事の数に初期化します。
そして、記事を1つ出力するごとに、連番を1つずつ減らすようにします。
初期化の部分は以下のように変えます。
<MTDateHeader> <MTSetVarBlock name="day_key"><$MTEntryDate format="%Y%m%d"></MTSetVarBlock> <MTSetVarBlock name="ctr"><MTGetVar name="day_count" key="$day_key"></MTSetVarBlock> </MTDateHeader>
また、連番を出力する部分は以下のように変えます。
<MTIf name="day_count" key="$day_key" ge="2"> -<MTGetVar name="ctr"> <MTSetVar name="ctr" op="--"> </MTIf>









コメントはスレッド表示になっています。
また、スレッドの先頭のコメントに対する返信には、先頭に矢印を表示しています。
はじめまして。
困っている件が、本エントリーの内容と若干重複する点があり、質問させてください。
某掲示板でも質問したのですが、難しい部類に入るようでレスがありませんでした。
実現したいのは、
インデックステンプレートにて10件ほど適当なカテゴリーに属す最新のエントリーが並んでいるページで、
「各エントリーのタイトル脇に、そのエントリーが属すカテゴリー内でその記事が何番目の記事か表示したい」
例えば、
「カルボナーラ(記事タイトル) 今日の夕食(カテゴリー) No.33(カテゴリー内での順番)」
という感じになります。ちなみにカッコ内は実際にはありません。
要は時系列のナンバー数になります。
エントリーの属すカテゴリの記事総数は出せるのですが、
「該当記事が各カテゴリー内で何番目なのか」は、
どう処理させればよいのか詰まっております。
配列に記事タイトルを全部入れて、連番を振り。。。とかでしょうか。
とはいえ、いちいちすべてのエントリーに対して処理するのもナンセンスかなと思いつつ、よくわからずといったところです。
わかりづらい説明で恐縮ですが、
アドバイスなどいただけると助かります。
>成海さん
こんにちは。
ご質問の件ですが、拙作のSuperSortプラグインを使うと、記事を並べ替えた上で、連番を振ることができます。
記事を時系列順に並べ替えることもできますので、このプラグインを使うのが簡単だと思います。
http://www.h-fj.com/blog/mtplgdoc/supersort.php
アドバイスありがとうございます

試行錯誤しているのですが、糸口が見つかりません
SuperSortプラグインのメイン機能は「任意で設定したカテゴリー順をいろいろな状況で使える」
ということだと思うのですが、
これをどう利用すれば「特定の記事がその記事が属しているカテゴリー内では何番目か」を導けるのでしょうか。
私が非力すぎてプラグインの有力さについていけず、ホントすみません。
>成海さん
こんにちは。
SuperSortプラグインは、カテゴリだけでなく、フォルダ/ブログ記事/ウェブページも自由な順序に並べ替えることができます。
また、並び順の番号もデータとして保存しています。
MTEntryOrderNumberというタグで、「カテゴリ内でのその記事の並び順の番号」を出力することもできます。
http://www.h-fj.com/blog/archives/2008/10/26-103943.php
ご希望の件ですが、カテゴリ内の個々の記事に、日付の古い順に番号を振るとすれば、以下の手順になります。
1.プラグインをインストールし、並び順を初期化化する際に、ブログ記事の並び順を「ブログ記事の日付順」にします。
2.インデックステンプレートで、記事のカテゴリを出力する部分を以下のようにします。
<mt:EntryCategories glue=", "><a href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a> No.<$mt:EntryOrderNumber$></mt:EntryCategories>
ありがとうございます
実はご提示いただいたソースくらいまでは行き着いていたのですが、<$mt:EntryOrderNumber$>の部分だけが表示されなかったのです。
<MTTopLevelCategories sort_method="SortCatFld::Sort">系のタグで囲わないと使えないもの、という認識で良いのか、悪いのかわからなくなってしまい、加えてMTTopLevelCategoriesなんてのはここでは関係ないし。。。
と試行錯誤中です。
ちなみにプラグインの設定画面で確認を押すと「カテゴリとブログ記事の並び順の初期化」というタイトルの画面で中身に何も表示されていない状態で動かなくなりますが、これは正しい挙動なのでしょうか。
すみません
先ほどのコメント漏れだらけだったので、消えたタグの部分を改めました。
mt:EntryOrderNumberの部分だけが表示されなかったのです。
と
MTTopLevelCategories sort_method="SortCatFld::Sort"系のタグで囲わないと
でした。
>成海さん
こんにちは。
>ちなみにプラグインの設定画面で確認を押すと「カテゴリとブログ記事の並び順の初期化」というタイトルの画面で中身に何も表示されていない状態で動かなくなりますが、これは正しい挙動なのでしょうか。
それは正しくない動作です。
初期化の際には、Ajaxを使って徐々に初期化の処理を進めて、初期化の状況を表示するようにしています。
いただいた状況からすると、Ajaxが動作していないようです。
MTの設定ファイル(mt-config.cgi)の「StaticWebPath」の設定が「http://~」のURLの形になっていたら、「http://○○.com」等の「http://」とドメイン名の部分を削除して、その後のアドレスだけを指定するように変えてみてください。
例えば、StaticWebPathが以下のようになっているとします。
StaticWebPath http://www.hoge.com/mt/mt-static/
この場合は、以下のように書き換えます。
StaticWebPath /mt/mt-static/
なお、個々のブログ記事のMTEntryOrderNumberタグの値は、初期化の際に設定しています。
したがって、初期化が終わらないと、今起こっているように、タグの値が何も表示されないことになります。
できました!
うまくいかなかった原因は「カテゴリとフォルダの並べ替え」プラグインを削除し忘れていたことと、それをやり直す際にアップするディレクトリを間違えている状態で一度作業してしまったので、諸々の不具合が連鎖したようです。
完全に私のミスでご迷惑お掛けしてしまいまいしたが、クリアになってとても有難く思います。
以前は「カテゴリとブログ記事の並べ替え」のページはなかったような気もしますが、これはこれですごいですね。
SuperSortのSuperさをもっと味わえるよう、もっといじってみます。
ありがとうございました
ありがとうございます
早速mt-config.cgiを確認しましたが、「http://」は入っていませんでした。
初期化しないと機能しないんですね。なるほどです。
取り急ぎご報告まで。
firefox3、MTは4.25です。
す。。。すみません。
Ajax機能して初期化できました。
リトライします!