MTLoop の仕様に注意
タイトルの通りなのだが、「なんのこっちゃ」と思われるだろう。Movable Type というブログ・システムの話だが、少々マニアックな内容だ。
Movable Type: 世界標準の CMS プラットフォーム
実例を挙げる。そのほうが話が早い。
MT4.1x 以上で、下記ページのサンプルコードを適当なインデックス・テンプレートに張り付けて実行する。
期待通りの結果(月の略称と名称が並んだリスト)が得られるはずだ。
さて、本題だ。上に挙げたサンプルに対して「8 月は除いて表示したい」と思ったとする。あなたなら、どう書く? ただし、<mt:loop>
の内部のみを書き換える、というのが条件だ。
- 自分の環境:
- Movable Type Commercial version 4.23-ja with: Professional Pack 1.21
- XREA の s300 サーバを利用: VALUE DOMAIN:バリュードメイン
MTLoop と MTIf の危険な関係
「簡単だ、MT ならば造作もないことだ」と次のように書き換えたとする:
<mt:Loop name="month" sort_by="value">
<!-- If 文を追加! -->
<mt:If name="__key__" ne="Aug">
<li><$mt:Var name="__key__"$>: <$mt:Var name="__value__"$></li>
</mt:If>
</mt:Loop>
しかし、この簡単なコードは思った通りに動作しない。プログラムは「書いたとおりに動く」はずなのだが、なぜか下のような呪文が表示される:
- Apr: HASH(0x9743d0c)
- Dec: HASH(0x9743d0c)
- Feb: HASH(0x9743d0c)
- (……)
うーむ、これは Perl のハッシュシステムとかリファレンスを直接見たような、デバッガを起動したような結果だ。
ちなみに、MTUnless
でも同じ結果になる。ne
を eq
に変えようが、意図した結果にはならない。
MTLoop
の内部では MTIf
文は使えないのだろうか?
解決策
直感で試したらウマく行った。__value__
の値を変数にコピーしてから使えばいいのだ。このように:
<mt:Loop name="month" sort_by="value">
<!-- MTSetVarBlock で __value__ を変数に格納する -->
<mt:SetVarBlock name="hash_value"><$mt:Var name="__value__"$></mt:setVarBlock>
<mt:If name="__key__" ne="Aug">
<!-- 変数から取り出す -->
<li><$mt:Var name="__key__"$>: <$mt:Var name="hash_value"$></li>
</mt:If>
</mt:Loop>
これまた奇妙なのだが、__value__
を変数へ代入するには MTSetVarBlock
しかダメだった。MTSetVar
で代入すると、また HASH
地獄になる。なぜ?
後日談
明らかに異常な動作と思い、Six Apart タンへ突撃・告白してみた(訳: ウェブページ上のフォームからフィードバック)。
asiamoth「あ、あの、オデ、むーばぶる・たいぽ──たいぷの動作でェ、なんか、おかしな所を見つけてェ(以下 1000 文字ほど省略)」
中の人「仕様です」
──そっスか。
(いちおう書いておくけど、きちんとビジネスライクな文章でやり取りしている Yo!)
ということで、「誠に恐れ入りますが、現在の製品の仕様により、MTLoop内のMTIf, MTUnlessの中で __value__ を使用することはできません。ご了承ください。
」(原文ママ・Movable Type 品質保証チームより)とのこと。
上の解決策のように、値をコピーして使おう。
Enjoy!
asiamoth ha Movable Type no rihabiri-tyuu desu