NVelocityの構成要素と全体の流れ
NVelocityを利用したアプリケーションの全体的な流れを図にまとめます。

また、NVelocityを構成する要素を下表に整理します。テキストの雛形となる「テンプレート」と、テンプレートで使用する変数を格納する「コンテキスト」が重要なキーワードとなりますので概要を理解しておくと良いでしょう。
| 名前 | 説明 |
| テンプレート(*.vmファイル) | 生成するテキストの雛形となるファイル |
| 初期設定ファイル | ログ出力先やエンコードの設定など |
| NVelocity | NVelocity本体 |
| NVelocityContext(コンテキスト) | テンプレートで使用する変数を格納 |
サンプルの構成とプログラミング手順
それでは、メールで送信する文面を生成するアプリケーションを作成していきます。まず、完成形の画面イメージとコントロールの名前は次のようになります。

NVelocityを利用したプログラミングでは次の手順で開発を進めていきます。
- テンプレートファイルの記述
- NVelocityの初期化(プログラミング)
- コンテキストの設定(プログラミング)
- テンプレートとコンテキストのマージ(プログラミング)
テンプレートファイルの記述
まず、テンプレートファイルを記述します。テンプレートファイルは一般的に拡張子がVM(Velocity Macroの略)のファイル形式で作成します。ここでは「mail.vm」というファイルを作成します。
「mail.vm」の全体像
本稿では、「mail.vm」を次のように記述します。詳細については、この後で個別に説明していきます。
##━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
## テンプレートファイル(mail.vm)
## Velocity テンプレート言語 (VTL) で記述します
##━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$name 様
ご注文ありがとうございます。
下記の通り配送させて頂きます。
▼住所
$address
▼備考
#if ($remarks == '')
なし
#else
$remarks
#end
▼ご注文商品
#foreach( $order in $orderlist )
$velocityCount $order
#end
▼お届け希望日
$senddate.Value.ToString("yyyy/MM/dd(ddd)")
-------------------------------------
※5月中は優待キャンペーン実施中です。
http://www.hogemoge.com/campaign/
#set( $telno = "012-345-6789" )
TEL $telno
-------------------------------------
VTLの基本構文
上記のテンプレートでは「$」や「#」といった記号が特別な意味で使われています。このようにNVelocityでは、VTL(Velocity Template Language)という言語でテンプレートを記述します。新しい言語と聞くと不安に感じるかもしれませんが、文法自体はとてもシンプルなので他のプログラミング言語の基本を知っている人であれば簡単に理解できるでしょう。
VTLの基本的な構文を下表に整理します。
| 構文 | 説明 |
## |
行コメントを記述する。この行はコメントとなり出力されない。 |
#*~*# |
範囲を指定してコメントを記述する。この記号の間はコメントとなり出力されない。 |
$変数名 |
コンテキストに設定された変数名の値を参照する。コンテキストにその変数名が設定されていない場合は、$変数名がそのまま表示される。 |
${変数名} |
$変数名と同義。変数名と出力する文字の間にスペースがない場合に使用する(例:「$name様」と出力したい場合「$name様」ではなく「${name}様」と指定する)。 |
$!変数名( $!{変数名}) |
$変数名と同義。ただし、コンテキストにその変数名が設定されていない場合は$変数名が空白で表示される。 |
\ |
エスケープ文字(例:「$name」という文字をそのまま出力したい場合は「\$name」)。 |
#foreach($変数名1 in $変数名2)~#end |
繰り返し処理を行う。変数名2にコレクション(リスト)を設定すれば、変数名1にコレクション内のオブジェクトが設定される。 |
#if(条件式)~#elseif(条件式)~#else~#end |
条件分岐を処理を行う。条件式の演算子は「==、>=、<=、!=」が使用可能。 |
#include(ファイル名) |
他のファイルを読み込む(日本語の場合UNICODEでないと文字化けします)。 |
#set($変数名 = 値) |
変数に値を代入する。 |
詳細については、VelocityのVTLリファレンス翻訳ページなどを参考にすると良いでしょう注1。
#parse、#macro、変数の配列は使用できませんでした。「mail.vm」の詳細解説
それでは、テンプレートファイル「mail.vm」の設定内容を上から順に説明していきましょう。
コメントの利用
##から始まる行はすべてコメント行となるため、出力結果には含まれません。vmファイルを読みやすくするための説明を記述します。なお、#*と*#ではさまれた文字もコメントとなります。
##━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ## テンプレートファイル(mail.vm) ## Velocity テンプレート言語 (VTL) で記述します ##━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
変数の使用
ここでは、$nameと$addressが変数となります。
$name 様 ご注文ありがとうございます。 下記の通り配送させて頂きます。 ▼住所 $address
$から始まる変数名に動的に値が設定されます。変数名は大文字と小文字を区別し、英数字とハイフンとアンダーバーが使用できます。日本語名は使用できませんので注意してください。
if文による条件分岐
「#if~#else~#end」という構文によって条件分岐を行っています。ここでは、備考を意味するremarksが空白の場合には、「なし」という文言を表示し、空白以外の場合にはremarksをそのまま表示しています。なお、文字の出力位置がずれるため、C#やVB.NETのようにインデント(文字下げ)は使用しません。
▼備考 #if ($remarks == '') なし #else $remarks #end
foreachによる繰り返し(ループ)
#foreachという構文によって繰り返しの指定を行うことができます。inの後ろの変数(ここでは$orderlist)はコレクションやリストを設定します。コレクションにデータが格納されている場合は、NVelocityによってデータが取り出され、inの前の変数(ここでは$order)にセットされます。
▼ご注文商品 #foreach( $order in $orderlist ) $velocityCount $order #end
また、$velocityCountは、ループカウンタをあらわす特別な変数です。この変数は1から順にループの度にカウントアップしていきます。なお、この$velocityCountという変数名やループカウンタの開始数値は「NVelocity.properties」(初期設定ファイル)に記述することで変更できます。
メソッド/プロパティへのアクセス
変数には「文字列」だけでなく「オブジェクト」を設定することもできます。
▼お届け希望日
$senddate.Value.ToString("yyyy/MM/dd(ddd)")
この$senddateにはDateTimePickerコントロールという「オブジェクト」が設定されています。変数にオブジェクトが設定されている場合は「$変数名+ピリオド+メソッド名/プロパティ名」という形式で記述します(メソッド名の場合は、()や引数を指定する必要があります)。
これまでNVelocityは、テンプレートに文字列を埋め込むというイメージで理解してきたと思いますが、ここではテンプレートからC#やVB.NETのコードを動的に呼び出すことができると理解した方が分かりやすいでしょう。ただし、テンプレート内でのプロパティ/メソッド呼び出しは、ロジックとデザインの分離を不明確にする可能性がありますので、乱用するべきではないでしょう。
変数設定
ここでは、#set構文によって$telnoという変数に値を設定しています。これまではコンテキストに設定された値を利用してきましたが、このようにテンプレートファイル内で変数の値を設定することも可能です。
------------------------------------- ※5月中は優待キャンペーン実施中です。 http://www.hogemoge.com/campaign/ #set( $telno = "012-345-6789" ) TEL $telno -------------------------------------
以上、テンプレートファイルの記述が完成しました。
