社内で簡易的なメモを作ったのでそのまま転載
基本的な情報
バージョンによる動作差異がありますが、以下が非常に参考になります
http://www.jajakarta.org/velocity/velocity-1.4/docs-ja/user-guide.html
以下は、↑のリンクから特に特徴的なものを抜粋したものです。
Getterの省略
Velocityテンプレート上では、getterメソッドをpublicフィールドのように利用できます。
例:
${user.userId}
↓
user → Userクラスのインスタンスの場合、user.getUserId() と同等です。
{} と !
-
{}
: 変数がどこからどこまでかを表しますたとえば
$hoge
という変数に "あいうえお" という値が入っていたとして、
"あいうえおaiueo" と出力したい場合に、
$hogeaiueo
と記載してしまうと、変数$hoge
ではなく$hogeaiueo
という変数が参照されます。これを避けるために
${hoge}aiueo
とどこまでが変数かマークします。 -
!
: 変数が空の場合の出力制御変数が未定義やnullの場合に出力を抑制します。
$hoge
が未定義の場合に出力した場合に以下のような差異があります-
${hoge}
または$hoge
…"$hoge"
という文字列が出力 -
$!{hoge}
または$!hoge
… 何も出力されない
-
WEBで利用する場合
様々なWEBフレームワークと併せて利用することもあるかと思います。
その場合、velocity-tools というものを利用することになります。
https://velocity.apache.org/tools/devel/
中でも、velocity-struts を利用することで、
各スコープへの参照が自動化されます。
例:
- toolbox.xmlに定義されているか?
- 各サーブレットクラスのインスタンスか?
$request
$session
$application
- ローカル変数が定義されているか?
- requestスコープにattributeが存在するか?
- sessionスコープにattributeが存在するか?
- applicationスコープにattributeが存在するか?
「これなんで実行できてるんだろ・・・?」
みたいに思った場合は、toolbox.xmlに定義されてることが多いかもしれません。
マクロ
velocity-macro.vmというファイルに定義可能で、
view上で頻繁に登場する似た処理を関数っぽく作成しておくことができます。
velocityにはparse機能(他vmファイルを利用する機能)がありますが、
こちらはマクロと違い引数を渡すことができません。
感覚的には、
- よりロジック的なもの(
if
/foreach
などを使う)はマクロ - HTMLの部品化(metaタグとか)はparse
かな〜と思います。
velocityでちゃんと表示されない!!
90%が基本的なミスな気がする。(他の要因だったらすいません・・・)
例:
form.content.userId
で何回やっても取得できない
確認すること
-
form
はちゃんと値が入っているか? -
form
に該当するクラスにgetContent
メソッド(引数無し)が存在するか? -
content
に該当するクラスにgetUserId
メソッド(引数無し)が存在するか?
HTMLエスケープ
ReferenceInsertionEventHandler
を利用することで、
すべての値について表示前に割り込ませることが可能。
こちらが参考になりました。
http://blog.physalis.net/2013/05/01/velocity-escape.html
なお上記参考サイトの場合、エスケープを回避させたい場合に
変数名末尾に特定文字列(NoEscape)を付与した場合はエスケープさせないようにしています。
このままでももちろん大丈夫ですが、
あとでパっと見たときになんとなくわかりにくくなるので、
velocity-toolbox経由で呼べる関数に、何もしないダミー関数を用意しておき、
その関数でラップされている場合には回避するようにしたほうが個人的には好みです。
public String noescape(String org) {
// エスケープ回避用のダミー関数。
// 詳細はReferenceInsertionEventHandlerの実装クラスを参照
return org;
}
${utils.noescape(hoge)}
enumを呼びたい
FieldMethodizerで利用できなくもないです。
なんとなく強引な方法な気もするので、自己責任で。。。
public enum Hoge {
PIYO,
FUGA;
}
request.setAttribute("hoge", new FieldMethodizer(Hoge.class.getCanonicalName()));
${hoge.PIYO.name()}