Text Templating Transformatin Toolkitというものがある。T4Templateとか呼ばれてるらしい。
このBlogでごちゃごちゃ書くよりも、ここでスクリーンキャストを見るのがいいと思う。
個人的に、テンプレートエンジンとしてRubyのerbかJavaのvelocityを使ってたけど、T4Templateも道具箱の1つとしてとっといていいかもしれないと思った。
とりあえず、家のVisual Studio 2008には最初から入っているということなので、早速簡単なものを試してみようと思う。
便利ツール入れよう
T4 Editorというものがある。こいつを入れるとT4Templateを編集するときにシンタックスハイライトしてくれるようだ。素敵なので入れた。
Pro版とCommunity版があってPro版は買わないといけないらしい。ということでCommunity版をダウンロードした。
ホームページのダウンロードリンクからT4 Editor Community edition for VS 2008をダウンロードしてインストールをした。テンプレートを書いてるときに、コード補完とシンタックスハイライトしてくれるようになった。
やる気が出てきたぞ。
へローワールドを作ってみよう
何事もHello worldから始まる。ということでHello worldを出力するプログラムを出力するテンプレートを書いてみようと思う。正直、このサンプルはテンプレートエンジンの旨みを最大限に活かしてないものです。基本的な使い方を学ぶこと以外には使えません!
- T4TemplateTestAppという名前でConsoleアプリケーションを作成
- Template.ttという名前でテキストファイルを作成
- Template.ttにHello worldを表示するC#のプログラムを書く
using System;
namespace T4TemplateTestApp
{
public class Greeter
{
public void Print()
{
Console.WriteLine("Hello world");
}
}
}
- Template.csを開くと、Template.ttに書いたものがそのまま出力されている
- Program.csでGreeterクラスを使う
namespace T4TemplateTestApp
{
class Program
{
static void Main(string[] args)
{
new Greeter().Print();
}
}
}
これでHello worldの完成。実行結果は、見慣れた風景なので割愛です。
もうちょっと頑張ろう
さっきのサンプルじゃあんまりなんで、10回Hello worldを表示するくらいに頑張ってみようと思う。
その前に、手抜きだったTemplate.ttファイルをちゃんと書いてみようと思う。
ディレクティブ
テンプレートファイルには、ディレクティブを書いておいたほうが多分すっきりする。ディレクティブは<#@ #>で括って記述する。
templateとoutputを、とりあえず指定してみた。templateにはlanguageを指定できて、テンプレート内で使う言語を指定できる。デフォはC#になっている。
outputはextensionを指定できて、生成するファイルの拡張子を設定できる。デフォは.csみたいだ。デフォの値そのままだけど、とりあえずファイルの先頭にディレクティブを入れてみた。
<#@ template language="C#" #>
<#@ output extension=".cs" #>
using System;
namespace T4TemplateTestApp
{
public class Greeter
{
public void Print()
{
Console.WriteLine("Hello world");
}
}
}
何だかそれっぽくなってきた。ディレクティブが終わったらついにテンプレートの本体を書いていく。
最初のサンプルでわかるとおり、何も考えずにテキストを書くと、そのままC#のファイルに出力される。ここに、何かロジックとかを埋め込みたいと思った場合は、<# #>で挟み込む。ためしにConsole.WriteLineの行をforループで囲ってみた。
<#@ template language="C#" #>
<#@ output extension=".cs" #>
using System;
namespace T4TemplateTestApp
{
public class Greeter
{
public void Print()
{
<#
for (int i = 0; i < 10; i++)
{
#>
Console.WriteLine("Hello world");
<#
}
#>
}
}
}
Template.csには予想通り10回へローワールドを出力するコードが書かれている。
using System;
namespace T4TemplateTestApp
{
public class Greeter
{
public void Print()
{
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
Console.WriteLine("Hello world");
}
}
}
これで固定値を繰り返し表示出来るようになった。じゃぁ可変の値を埋め込むには??となってくる。
これには<#= #>を使う。これで挟まれた部分の評価結果が、文字列の中に埋め込まれる。さっきのハローワールドにループカウンタの値もあわせて表示するようにしてみると下のような感じになる。
<#@ template language="C#" #>
<#@ output extension=".cs" #>
using System;
namespace T4TemplateTestApp
{
public class Greeter
{
public void Print()
{
<#
for (int i = 0; i < 10; i++)
{
#>
Console.WriteLine("Hello world<#= i #>");
<#
}
#>
}
}
}
ちゃんと1~9までが表示されている。
using System;
namespace T4TemplateTestApp
{
public class Greeter
{
public void Print()
{
Console.WriteLine("Hello world0");
Console.WriteLine("Hello world1");
Console.WriteLine("Hello world2");
Console.WriteLine("Hello world3");
Console.WriteLine("Hello world4");
Console.WriteLine("Hello world5");
Console.WriteLine("Hello world6");
Console.WriteLine("Hello world7");
Console.WriteLine("Hello world8");
Console.WriteLine("Hello world9");
}
}
}
ちなみに、テンプレート内の<# #>の間に書けるコードはC#2.0相当っぽい。ラムダ式とかは使えなかった。残念。