これは Movable Type Advent Calendar 2014 の14日目の記事です。
今年も早いもので、あっという間に年末ですね。。。
さて、最近になって配列やハッシュを利用し、テンプレートタグだけで処理をする機会が増えました。
Movable Type 3 から使っているものの、今更ながらに気づいたことがいくつかありましたので、備忘録をかねて共有してみます。
そもそも、Movable Type の配列・ハッシュとは?
配列やハッシュの基本は公式リファレンスで解説されているので、そちらにお任せを w
配列、ハッシュ、<mt:loop>、<mt:for> | movabletype/Documentation Wiki:
https://github.com/movabletype/Documentation/wiki/Japanese-mtml-guide-3-3
variable タグを含むテンプレートタグ | テンプレートタグリファレンス:
http://app.movabletype.jp/mt/mt-search.cgi?IncludeBlogs=3&tag=variable&SearchSortBy=title&SearchResultDisplay=ascend
あわせて VarDump プラグインを利用すれば、変数の構造を簡単に確認できます。
alfasado/mt-plugin-var_dump:
https://github.com/alfasado/mt-plugin-var_dump
name / key / setvar モディファイアの値は日本語表記できる
公式リファレンスはもちろん、過去に目にした書籍やブログ記事などで変数名(ハッシュのキー)はいつも半角英数で記述されているため、てっきり「できないもの」と思い込んでましたが、日本語表記でも動くのですね。
ただし、下記コードのように「$変数名」の形で参照することはできません。
<mt:EntryTitle setvar="記事タイトル" />
<mt:Setvar name="タイトル" value="$記事タイトル" />
<mt:Var name="タイトル" /> <!-- 「$記事タイトル」と出力される -->
実際に利用することはないと思いますが、意外な発見でした。
MTLoop は入れ子にできる
これも単に試していなかっただけなのですが、下記のように入れ子になった MTLoop も普通に処理されるのですね。
<mt:Loop name="hashSample">
__key__=<mt:Var name="__key__" /><br>
<mt:Loop name="__value__" sort_by="key">
__subKey__=<mt:Var name="__key__" />:__subValue__<mt:Var name="__value__" /><br>
</mt:Loop>
</mt:Loop>
もしや?と思ってやってみたら、Movable Type 5.2.x でも大丈夫でした。
index / key モディファイアで悶々とする
インデックス番号を明示的に指定して配列を作ろうとしたとき、頭の中では下記と同じ出力結果になるだろうと考えていました。
<?php
$hashSample = array(
1 => 'hoge',
10 => 'hoge10',
5 => 'hoge5'
);
ksort($hashSample, SORT_NUMERIC);
foreach ($hashSample as $key => $value) {
echo $key . ':' . $value . '<br>' . PHP_EOL;
}
?>
<!-- 出力結果 -->
1:hoge
5:hoge5
10:hoge10
ところが、MT タグで同じように値をセットしたところ、思いもよらない結果に。。。
<mt:SetVar name="hashSample" />
<mt:SetVar name="hashSample" index="1" value="hoge1" />
<mt:SetVar name="hashSample" index="10" value="hoge10" />
<mt:SetVar name="hashSample" index="5" value="hoge5" />
<mt:Loop name="hashSample">
<mt:Var name="__counter__" op="--" />:<mt:Var name="__value__" /><br>
</mt:Loop>
<!-- 出力結果 -->
0:
1:hoge1
2:
3:
4:
5:hoge5
6:
7:
8:
9:
10:hoge10
無駄なループを避けるため、key モディファイアが無難かな?と思いきや。。。
<mt:SetVar name="hashSample" />
<mt:SetHashVar name="hashSample">
<mt:SetVar name="1" value="hoge1" />
<mt:SetVar name="10" value="hoge10" />
<mt:SetVar name="5" value="hoge5" />
</mt:SetHashVar>
<mt:Loop name="hashSample" sort_by="key">
<mt:Var name="__key__" />:<mt:Var name="__value__" /><br>
</mt:Loop>
<!-- 出力結果 -->
1:hoge
10:hoge10
5:hoge5
MTLoop のキーを基準とする並び替えでは numeric サブモディファイアが使えないということを覚えました。
sort_by モディファイア なしの MTLoop は、結果がランダムになる
以前、DataAPI のレスポンスを眺めていて不思議に感じたことでもあるのですが、sort_by モディファイアの指定がない MTLoop が実行されたとき、出力結果は(スタティックの場合)再構築するごとに変わってしまうのですね。
記事データなどの更新にあわせてであれば、内部的なルールがあるのだろう・・・と納得できるものの、個人的にモヤッとしました。
2次元ハッシュの値も、意外と簡単に変更できる?
2次元ハッシュの値は、一旦別の変数に入れたものに key モディファイア を指定すれば取得できます。
<!-- 間違った例 -->
<mt:Var name="hashSample{foo}" key="bar" />
<mt:Var name="hashSample{foo}{bar}" />
<!-- 正しい例 -->
<mt:Var name="hashSample" key="foo" setvar="hashSub" />
<mt:Var name="hashSub" key="bar" />
これと同じように、値を変更することもできるのですね。
<mt:Var name="hashSample" key="foo" setvar="hashSub" />
<mt:SetVar name="hashSub" key="bar" value="hoge" />
この後 MTLoop で出力すると値が上書きされていることを確認できるものの、前述の VarDump プラグインの出力結果では正しくセットされていたり・いなかったり・・・なので、素直にループ処理の中で更新した方がよいのかも?とは思いつつ。
最後に
今回は配列やハッシュについて気づいた点をまとめてみましたが、他にも過去に覚えたことを引きずっている可能性が否定できず、折りに触れ初心にかえって基本を見直すことは大事だな・・・と改めて感じました。
ということで。。。
先日発足した東北界隈を中心とする Movable Type ユーザーグループもよろしくお願いいたします w
MT東北(Facebook ページ):
https://www.facebook.com/mt.tohoku