Velocityの文法


VTLについて

Velocityの文法はVelocity Template Language(VTL)とも呼ばれます。

変数について

テンプレート中に値を入れるのに変数を使います。
変数は$から始まります。

 形式 値が空の場合 用途
 $name 変数名を表示 普通
 ${name} 変数名を表示 英文の中で境界が曖昧な場合
 $!name 何も表示しない 値が空の時表示させたくない場合

変数名に使える文字

変数名には以下の文字しか使えません。
先頭の文字は小文字か大文字の英字でないといけません。
  • a-z A-Z
  • 0-9
  • - (ハイフン)
  • _ (アンダーバー)

カギ括弧でくくる形式

変数は、単純に$name とカギ括弧でくくる ${name} という書き方ができます。

英数字だけの文字の間に入れる場合は、カギ括弧でくくる必要があります。
例: abc${D}efg

それ以外にもカギ括弧の方が見落としにくい気がします。
私はデザイナーの方と共同作業の時は、カギ括弧つきを使っています。

値が指定されていないとき何も表示しない変数

Velocityでは変数の値が無い場合、そのまま変数の名を表示します。
しかし$のあとに!を書くことで値が設定されていない場合空になるようにできます。
一方値の指定を忘れた場合、気づきにくいので注意が必要です。

例のようなフォームの値の置き換えとかには便利そうですね。
<input value='$!value'/>

またカギ括弧でくくる形式でも使えます。
<input value='$!{value}'/>

コメント

コメント中の文字は実行時に表示されません。テンプレート中にコメントを入れるとわかりやすくなります。

1行コメント

##のあとに続く行はコメントになります。もちろん、行の途中から始まっても構いません。
##comment
Hello $value.

Hello $value.##comment

複数行コメント

複数行をコメントしたい場合は、コメント開始と#*   コメント終了*#で挟みます。行の途中から始まっても構いません。
#*
comment
comment
*#

hello #*comment*# $value.

別のファイルを読み込む

VMファイルとして読み込む

ヘッダーやフッターは別のファイルに分けて、読み込むほうが便利な場合もあります。
別のVMファイルを読み込む場合、#parseを使います。

#parse("body_header.vm.html")
$data
#parse("body_footer.vm.html")

 ただし、ファイルの位置は、現在位置からの相対になります。
プログラムの直下に置いている場合はいいですが、templateフォルダーにまとめていたりする場合、以下のようにパスがVelocityの初期化前に指定しないと
Velocity.setProperty("file.resource.loader.path","template" );

org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource
のようなエラーが出ます。

またparseの括弧の中でダブルコーテションを省くと、以下のようなエラーが出ますので、必ず括弧でくくります。
org.apache.velocity.exception.ParseErrorException: Invalid arg #0 in directive #parselogTag[line *, column *]

普通のテキストして読み込む

普通のファイルとして読み込む場合、#includeを使います。

#include("test.vm")

そうすると、ファイル中に、Velocityの文法があっても無視されそのまま#set やら $value とかそのまま表示されます。

ループについて

ループを作成

foreach を使います。
値名 in リスト名 となります。
mapから、keyset()を取り出して、リスト名とすることもできる。 
ループの最後には必ず #end行を入れます。

#foreach ($data in $list)
$data.name
#end

ループ中のindex番号について

velocityCountには、ループ中の回数が入ります。
ちなみに、次の値があるかどうかは、velocityHasNextで知ることができます。
ただ多重配列で外側の数を得るには、何らかの工夫が必要になるでしょう。

#foreach( $title in ["a","b","c"] ) $title $velocityCount $velocityHasNext #end

を実行すると 以下のようになります

a 1 true b 2 true c 3 false


これら変数名は、Velocity設定の以下を修正することで変更出来ます。
directive.foreach.counter.name = velocityCount
directive.foreach.iterator.name = velocityHasNext

多重配列でのindex番号

いまいち、上手なやり方わかりませんが、インデックスの値を自分で保存する必要があります。
現在、Velocity Generic ToolsのLoopToolで作成中見たいです。

私はこういう風にしています。

 <table border=1>
 #set($i=0) 
 #foreach( $cells in [["a","b"],["c","d"]])
 <tr><td>$velocityCount</td>
 #set($j=0) 
 #foreach($item in $cells)
 <td>${i}-$j $item</td>
 #set($j=$j + 1) 
 #end
 </tr>
  #set($i=$i + 1)
 #end
 </table>

実行すると以下のようなテーブルができます。
(下テキストはテーブルではないですが)
0-0 a 0-1 b
1-0 c 1-1 d

ループの最初と途中と最後で分岐

こういう風に分岐します
#foreach( $value in ["a","b","c","d"]) #if($velocityCount==1) 最初 $value #elseif($velocityHasNext) 途中 $value #else 最後 $value #end #end
実行するとこうなります。
最初 a 途中 b 途中 c 最後 d

loopからのbreak

長らくbreakがないことで不自由がありましたが、Velocityバージョン1.6よりloop中にbreak文法が使えるようになりました。
(一方continueはまだありません)

#foreach( $title in $titles )
    #if( $velocityCount > 1 )
        #break
    #end
    $title
#end

分岐に付いて

if で分岐

ifの後に条件文を書きます。
分岐の最後には必ず#end行を入れます

#if($value > 3)
$value
#end
まれにスペースとか空けないとうまくパースできない条件もあるので注意

else if と else

else ifやelse も普通の文法のように使えます。
else ifはelseifとスペースを空けずに記述します。
#if( $age < 20 ) 十代 #elseif( $age <30 ) 二十台 #elseif( $age <40 ) 三十台 #else その他 #end

Nullで分岐 

null以外は、true ・nullはfalseに変換されるのを使ってチェックするのがいいでしょう。
#if($value)
nullでない時
#end

Comments