X

MTLoop 内で MTIf, MTUnless を使うと __value__ が異常になる

MTLoop の仕様に注意

(by Thomas Hawk)

タイトルの通りなのだが、「なんのこっちゃ」と思われるだろう。Movable Type というブログ・システムの話だが、少々マニアックな内容だ。

Movable Type: 世界標準の CMS プラットフォーム

実例を挙げる。そのほうが話が早い。

MT4.1x 以上で、下記ページのサンプルコードを適当なインデックス・テンプレートに張り付けて実行する。

MTLoop | テンプレートタグリファレンス

期待通りの結果(月の略称と名称が並んだリスト)が得られるはずだ。

さて、本題だ。上に挙げたサンプルに対して「8 月は除いて表示したい」と思ったとする。あなたなら、どう書く? ただし、<mt:loop> の内部のみを書き換える、というのが条件だ。

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 でも同じ結果になる。neeq に変えようが、意図した結果にはならない。

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

asiamoth: