Movable Typeのmt:SetVarTemplateやmt:Includeを拡張してみる

こんなツイートがあったので、mt:SetVarTemplateやmt:Includeでextend的なのやってみようと思います。

要件を満たせているか、わかりませんがうまくMTMLでやる方法を紹介したいと思います。
所謂、ファンクションタグの活用で実装は可能なのかなって思ったりしています。

mt:Includeで拡張してみる

mt:Includeはテンプレートモジュールとして使われるタグですが、
一般的にヘッダーやフッターなど、共通で使う部分をまとめたりしてサイトを制作します。

以下のようなコードで、テンプレートモジュールを作ります。
この時にHTMLのclassの値を変数(mt:Var)を定義させます。

  
// テンプレートモジュール名(header)
<header id="header" class="<mt:Var name="header_classname" />">
  <h1>サイト ロゴ</h1>
</header><!-- /header -->
  

出力のテンプレートには、以下のようなコードで書きます。
mt:Includeのタグにファンクションタグを定義します。※変数名="value"

  
// 出力テンプレート(インデックステンプレートやアーカイブテンプレートなど)
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ヘッダーのclass名を入れる</title>
</head>
<body>
<mt:Include module="header" header_classname="site_header" />
</body>
</html>
  

出力結果

出力結果は以下のように、ファンクションタグで定義した値が、出力されるようになります。

  
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ヘッダーのclass名を入れる</title>
</head>
<body>
<header id="header" class="site_header">
  <h1>サイト ロゴ</h1>
</header><!-- /header -->
</body>
</html>
  

条件分岐で出し分けることも可能

ただ出力させるだけでは芸がありません。
条件に応じて使い分けをしてみます。


Aテンプレートではclassを出力させ、Bテンプレートではclassを出力させない

先程のテンプレートモジュールに条件分岐を入れてみます。

  
<header id="header"<mt:If name="header_classname"> class="<mt:Var name="header_classname" />"</mt:If>>
  <h1>サイト ロゴ</h1>
</header><!-- /header -->
  

以下のように、出力側のテンプレートモジュールには、ファンクションタグありとなしで出し分けを制御することが可能になります。

  
// classが必要の場合は定義(Aテンプレート)
<mt:Include module="header" header_classname="site_header" />
// classが不要の場合は未定義(Bテンプレート)
<mt:Include module="header" />
  

初期値を決めておくことも可能

defaultモディファイアを使うことで、初期値を設定することも可能です。
MTには様々なモディファイアが用意されています。
mt:Varに対してdefaultモディファイアを使うことで、
ファンクションタグが定義されていなかった場合、defaultに設定した初期値を出力してくれます。

  
<header id="header" class="<mt:Var name="header_classname" default="original_class" />">
  <h1>サイト ロゴ</h1>
</header><!-- /header -->
  

極端な例の紹介ですが、実際の構築ではconfigモジュールなどで、変数定義しておくと便利だったりします。
このファンクションタグは、かなり前から使える機能です。
共通だけど、この出力テンプレートだけ少し変えたいなどには有効な方法になります。
やりすぎると見通しが悪くなるので、適材適所に使用することをおすすめします。

mt:SetVarTemplateで拡張してみる

mt:SetVarTemplateでも同じことが可能です。
私個人の実装方法としては、SetVarTemplateで管理していることが多いです。

以下のようなボタンのモジュールをSetVarTemplateで定義します。
今回、ファンクションタグを定義したのは3つになります。

  • ボタンリンクのclass名
  • リンク先
  • ボタン名
  
<mt:SetVarTemplate name="_base_button" key="button" note="ボタンのモジュール">
<div class="button">
  <a class="button__link<mt:Var name="_button__is_class" />" href="<mt:Var name="_button_link" />">
    <mt:Var name="_button_name" />
  </a>
</div>
</mt:SetVarTemplate>
  

出力のテンプレートには、以下のようなコードで書きます。
mt:Includeと同様にSetVarTemplate内で定義したmt:Varをファンクションタグとして使用することも可能です。

  
<mt:Var name="_base_button"
        key="button"
        _button__is_class=" button__link--about"
        _button_link="/about/"
        _button_name="Aboutページへ"
        note="aboutページのボタン"
 />
  

出力結果

出力結果は以下のように、ファンクションタグで定義した値が、出力されるようになります。

  
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ヘッダーのclass名を入れる</title>
</head>
<body>
<div class="button">
  <a class="button__link button__link--about" href="/about/">
    Aboutページへ
  </a>
</div>
</body>
</html>
  

私は、このようなSetVarTemplateを記述したものを、functionモジュールで定義して使い回しをしています。
肥大していくと見通しが悪いMTMLになるため、mt:Include同様に適材適所に考えて設計していくことを心がけています。
※MTあるあるですが、変数名にハイフンを使うと認識してくれません。

SetVarTemplateをこのように使うことで、コンポーネント化を意識した使い方ができます。
今回は、単純な例で紹介しましたが、条件分岐などを設定することで様々な使い方が可能になります。
汎用的なベースコーディングデータをMTMLとうまく移植できる形で作ることを意識していきたいですね。

参考記事

Author

札幌でフロントエンドエンジニアとして働いています。好きな音楽はSIAM SHADE!
SIAM SHADEの六人目のメンバーとして日々ロックを愛し続けている。
HTML,CSS,JavaScriptをベースにCMS構築が得意です。
HAMWORKS社員 https://ham.works