转载请注明出处: http://qiudeqing.com/java_web/2016/01/07/velocity.html

官方教程

基础语法

注释

velocity有两种注释

引用

velocity有三种类型的引用: 变量, 属性, 方法.

如果引用获取到的结果直接用于输出, 将会转化为字符串

变量(variable)引用

$ + 标识符组成一个变量引用, 如$foo. 变量引用可以获取上下文中的变量值, 也可以获取set指令设置的值

属性(property)引用

$customer.name 使用.访问对象属性相当于$customer.getName()的简写

属性按照一下方式查找(以$customer.address为例), 依次在customer下查找

  1. getaddress()
  2. getAddress()
  3. get(“address”)
  4. isAddress()

如果是$customer.Address, 顺序如下

  1. getAddress()
  2. getaddress()
  3. get(“Address”)
  4. isAddress()

方法(method)引用

$customer.getAddress()
$page.setTitle("My Home Page")
$person.setAttributes(["Strange", "Weird", "Excited"])

索引

$foo[0]相当于$foo.get(0)

$foo[0]     ## 使用整数查询
$foo[$i]    ## 使用另一个引用值查询
$foo["bar"]     ## 使用字符串查询

标准引用标记

${customer.Address}为标准引用标记, $customer.Address为简写, 通常情况下使用简写即可, 有些特殊情况下必须使用标准引用法.

比如需要输出vice属性值后面直接跟maniac

$vicemanic      ## 引起歧义
${vice}manic    ## 正确渲染

空值引用标记

velocity遇到未定义引用时, 通常是输出引用表达式原文.如在没有name属性定义的上线文渲染$name结果为$name.

使用$!name输出时, 如果变量未定义将输出空, 完整表达式为$!{name}

严格引用模式

velocity 1.6引入严格引用模式, 通过设置runtime.references.stricttrue即可. 严格引用模式下得变量必须在对应对象中定义, 否则会抛出异常

表达式等价

很多表达式具有等价作用

$foo.getBar()
## is the same as
$foo.Bar

$data.setUser("jon")
## is the same as
#set( $ata.User = "jon" )

$data.getRequest().getServerName()
## is the same as
$data.Request.ServerName
## is the same as
${data.Request.ServerName}

指令

指定以#开头, 与引用一样完整格式为#{if}, 简写为#if

set

#set指令用于设置引用值, 表达式放在括号中. 变量, 属性可以设置为值或者引用值

#set($primate = "monkey")
#set($customer.Behavior = $primate)

等号的左边必须是变量引用或者属性引用, 右边为以下类型之一

#set($monkey = $bill)   ## variable reference
#set($monkey.Friend = "monica")     ## string literal
#set($monkey.Blame = $whitehouse.Leak)      ## property reference
#set($monkey.Plan = $spindoctor.weave($web))    ## method reference
#set($monkey.Number = 123)      ## number literal
#set($monkey.Say = ["not", $my, "fault"])   ## ArrayList
#set($monkey.Map = {"banana": "good", "roast beef": "bad"})     ## Map

当值为ArrayList时变量可以使用$monkey.Say.get(0)获取元素

当值为Map时, 可以使用$monkey.Map.get("banana")获取值

等号右边也可以是简单数学表达式

#set($value = $foo + 1)
#set($value = $bar - 1)
#set($value = $foo * $bar)
#set($value = $foo / $bar)

如果等号右边属性或者方法返回值为null, 将不会赋值到左边变量. 也就是说不能通过set指令将变量设置为null, 如果确实需要设置, 应该先把变量设置为false然后查询

#set($criteria = ["name", "address"])

#foreach($criterion in $criteria)
    #set($result = false)
    #set($rsult = $query.criteria($criterion))

    #if($result)
        Query was successful
    #end
#end

字面量

#set指令中双引号包含的字符串会被解析并且渲染

#set($directoryRoot = "www")
#set($templateName = "index.vm")
#set($template = "$directoryRoot/$templateName")
$template

输出为

www/index.vm

单引号中的字符串不会被解析

使用#[[字符串]]#, 其中的字符串不会被解析, 如

#[[
#foreach($woogie in $boogie)
    nothing will happen to $woogie
#end
]]#

以上代码渲染为:

#foreach($woogie in $boogie)
    nothing will happen to $woogie
#end

条件选择if

if, elseif, else

#if指令表达式为真时里面的内容才会输出

#if ($foo)
    <strong>Velocity</strong>
#end

满足以下情况之一表达式$foo为真

velocity上下文只包含对象

#if ($foo < 10)
    1
#elseif ($foo == 10)
    2
#elseif ($bar == 6)
    3
#else
    4
#end

关系和逻辑运算符

#if ($foo == $bar)
    eq
#end

velocity比较不同对象时, 先用toString()转换为字符串再比较

#if ($foo && $bar)
    and
#end

两个表达式都为true时if内才渲染.

#if ($foo || $bar)
    or
#end

两个表达式之一为true时渲染

#if (!$foo)
    not
#end

$foo为false时渲染

也可以使用文本格式的逻辑运算符eq, ne, and, or, not, gt, ge, lt, le

循环

#foreach用于执行循环

<ul>
#foreach($product in $allProducts)
    <li>$product</li>
#end
</ul>

如果$allProducts是Hashtable, 可以这样遍历

#foreach($key in $allProducts.keySet())
    Key: $key -> value: $allProducts.get($key)
#end

获取循环次数

#foreach($customer in $customerList)
    $foreach.count : $customer.Name
    #if ($foreach.hasNext)
        ,
    #end
#end

引入模板

#include用于引入其他模板到指定位置. 模板引擎不会渲染引入的文件内容. 因为安全因素, 被引入的文件必须在TEMPLATE_ROOT下.

#include("one.text", "two.text", $seasonalstock)

引入并解析

#parse引入文件并解析, 一次只能引入一个文件

#parse("me.vm")