ひな型ファイルに埋め込まれたキーワードを置換するテンプレート・エンジンをVBで活用。ひな型に条件分岐なども記述できる。
powered by Insider.NET
StringTemplateは、「テンプレート・エンジン」と呼ばれる種類のコンポーネントです。テンプレート・エンジンとは、簡単にいうと、“ひな型”のファイルに外部からデータを埋め込み、テキストを出力するためのツールです。ひな型となるファイルには、あらかじめ特定のキーワードを埋め込んでおき、テンプレート・エンジンによりそれらのキーワードを変換します。
例えば、データベースに含まれる大量の製品情報をWebサイトのコンテンツとして作成したい場合、テンプレート・エンジンを使うことで、同じ形式の製品情報ページを自動作成できます。こうすることで、コンテンツの更新頻度が低いような場合は、Webサーバで動的にコンテンツを生成してブラウザに返すよりも、サーバの負担を軽くできる利点があります。また、ASP.NETなどでテンプレート・エンジンを使えば、アプリケーションの再ビルドを行うことなく、テンプレートを変更するだけでブラウザに返すコンテンツを変更できるようになります。
StringTemplateは、オリジナルはJavaによるものですが、.NET版がStringTemplate.NETとして公開されています。今回はこのStringTemplate.NET(以下、「StringTemplate」と記述)の概要を紹介します。
ちなみに、PHPではSmarty、JavaではVelocityなどがテンプレート・エンジンとしてよく利用されているようです。Velocityについては、.NET Frameworkに移植されたNVelocityも公開されていますが、Java版がアップデートを繰り返しているのに対して、.NET版は2003年から開発が止まっているようです。
StringTemplateはhttp://www.stringtemplate.org/からダウンロードできます。このサイトにアクセスすると、「C# StringTemplate binary distribution .NET 1.1」と「C# StringTemplate binary distribution .NET 2.0」の2つが用意されています。利用する.NET Frameworkのバージョンに合わせて選択してください。今回は、Version 3.0.1の.NET 2.0用のバイナリを使用します。
提供されるファイルはZIPファイルですので、適当なフォルダに展開します。StringTemplateのライブラリ、PDF形式とHTML形式のドキュメントなどが含まれています。インストーラは含まれません。今回は、「C:\StringTemplate」というフォルダを作成して展開しました。
また、以降ではVisual Studio 2008(以下、VS 2008)を用い、コンソール・アプリケーションのプロジェクトを新規作成して、プログラミングを行っています。
■参照の追加
StringTemplateをVS 2008で利用するための準備は、VS 2008のプロジェクトで参照の追加を行うことだけです。次の2つのライブラリへの参照を追加します。
参照の追加は、ソリューション・エクスプローラで[すべてのファイルを表示]ボタンをクリックして、プロジェクトのツリーから「参照設定」を選択した後、右クリック・メニューから[参照の追加]を選択するか、IDEのメニューから[プロジェクト]−[参照の追加]を選択します。
そして、[参照の追加]ダイアログで、[参照]タブを選択し、StringTemplateを展開したフォルダからantlr.runtime.dllとStringTemplate.dllを選択します。
ソース・コード(Module1.vb)の先頭には、次のImports文を追加しておきます。
Imports antlr.StringTemplate
Imports antlr.StringTemplate.Language
これでStringTemplateを利用する準備ができました。
まず始めに、テンプレート・エンジンを利用するうえで基本となる、キーワードの置換について見ていきます。
例えば、「こんにちは ○○ さん」というテキストの「○○」の部分を「岸本」に置換するには、次のようなコードを記述します。
Imports antlr.StringTemplate
Imports antlr.StringTemplate.Language
Module Module1
Sub Main()
proc01()
End Sub
Private Sub proc01()
Dim st As New StringTemplate("こんにちは $name$ さん")
st.SetAttribute("name", "岸本")
Console.WriteLine(st.ToString())
End Sub
End Module
StringTemplateオブジェクトの作成時に指定している「こんにちは $name$ さん」がテンプレートです。そして、このテキストに含まれる「$name$」を、StringTemplateでは「属性(Attribute)」と呼びます。属性は属性名を「$」で挟んで記述します(「$」の代わりに「<」と「>」を使用することもできます)。
次にテンプレート・オブジェクト(変数st)のSetAttributeメソッドを使って、属性にテキストを設定します。先頭の引数は属性名を指定します(「$」は付加しません)。2番目の引数には、変換を行う文字列を指定します。
これを実行するとコンソール画面に、
こんにちは 岸本 さん
と表示され、$name$の部分が「岸本」に置き換わります。
このように、StringTemplateを用いてテンプレートからテキストを生成する処理の基本は非常に単純です。以降では、StringTemplateに用意されているさまざまな機能を使って、もう少し現実的な処理を実装してみます。
実際にStringTemplateを利用する場面では、プログラムの中で文字列定数としてテンプレートを用意する機会は少なく、通常はテンプレートをファイルで用意し、これをプログラムで読み込んで処理します。
まず、テンプレートとなるファイルを用意します。このテンプレート・ファイルもVisual StudioのIDE内で編集できると便利なので、プロジェクトにテンプレート・ファイル用のフォルダを作成し、ここにテキスト・ファイルを作成します。拡張子は「.st」としておく必要があります。
作成したテンプレート・ファイルは、アプリケーションの実行時に参照しやすいように、プロパティ・ウィンドウの[出力ディレクトリにコピー]の項目で「新しい場合はコピーする」を選択しておきます。こうすると、ビルドと同時に実行ファイルと同じ場所(Debugビルドの場合はbin\debug)にテンプレート・ファイルがコピーされるようになります。
■テンプレート・ファイルの書式
1つのテンプレート・ファイルには複数のテンプレートを記述できますが、ファイル内にテンプレートを1つだけ記述する場合と、複数のテンプレートを記述する場合では、プログラム上でのテンプレート・ファイルの処理が異なります。
テンプレート・ファイルにテンプレートを1つだけ記述する場合は、固有の書式は必要ありません。例えばHTMLファイルを出力する場合、次のように通常のHTMLファイルと同様の内容で、必要に応じて属性を埋め込んだファイルを作成します。ここではtemplatesフォルダに「template01.st」というファイル名で作成しています。
<html>
<head></head>
<body>
<h1>こんにちは $name$ さん</h1>
</body>
</html>
作成したテンプレート・ファイルをアプリケーションで読み込んで処理するには、StringTemplateGroupクラスとStringTemplateクラスを使用します。
Private Sub proc02()
Dim grp As New StringTemplateGroup("myGroup", "templates")
Dim st As StringTemplate = grp.GetInstanceOf("template01")
st.SetAttribute("name", "岸本")
Console.WriteLine(st)
End Sub
まずStringTemplateGroupを用いてテンプレートのグループ名とテンプレート・ファイルを読み込むフォルダを指定します。単一のテンプレートを読み込む場合、グループ名に意味はないので適当な名前を指定しておきます。
2番目の引数にはテンプレートが格納されているフォルダを指定します。ドライブ名を指定しない場合は、実行ファイルのある場所からの相対位置を指定します。
文字列定数を扱う場合と異なり、テンプレート・ファイルの読み込みは、StringTemplateGroupクラスのGetInstanceOfメソッドで行います。引数にはテンプレート・ファイル名を指定しますが、拡張子は指定しません。このメソッドを実行すると、StringTemplateのインスタンスが取得できますので、これを使って、属性に内容を設定します。先ほどの例と同様に、変換結果をコンソール画面に表示しています。
■テンプレート・ファイルに複数のテンプレートを記述する場合
テンプレート・ファイルにテンプレートを複数記述する場合は、それぞれのテンプレートを識別できるようにしておく必要があります。次に示すように、まずテンプレート・グループの宣言を行い(group test;)、続いて個々のテンプレートを記述します。
group test;
template1(name) ::= "お名前:$name$"
template2(name) ::= <<
Your name: $name$
>>
各テンプレートは、
テンプレート名(属性) ::= ……
という書式で記述します。「属性」にはテンプレートで使用するすべての属性をカンマで区切って宣言します。テンプレートが単一行に収まる場合は、テンプレート部分をダブルクオーテーション(")で囲みます。複数行になる場合は、テンプレート本体を「<<」と「>>」で囲みます。
複数のテンプレートが記述されたテンプレート・ファイルを読み込む場合は、リスト5のようにStreamReaderクラス(System.IO名前空間)を用いて、テンプレート・ファイルの内容をStringTemplateGroupオブジェクトに読み込みます。続いて、そのGetInstanceOfメソッドを使って、テンプレートの指定を行います。先ほど(リスト3)と同じメソッドですが、単一のテンプレート・ファイルを読み込む場合はファイル名を指定し、複数のテンプレートが記述されたテンプレートを読み込む場合はテンプレート名を指定するという点が異なります。
Private Sub proc03()
Dim grp As New StringTemplateGroup( _
New StreamReader("templates\\template02.st"), _
GetType(DefaultTemplateLexer))
Dim st As StringTemplate
st = grp.GetInstanceOf("template1")
st.SetAttribute("name", "岸本")
Console.WriteLine(st)
st = grp.GetInstanceOf("template2")
st.SetAttribute("name", "岸本")
Console.WriteLine(st)
End Sub
この例では、テンプレート・ファイルに記述された2つのテンプレートを、GetInstanceOfメソッドを使って取得し、属性に値を設定しています。
Copyright© Digital Advantage Corp. All Rights Reserved.