velocity模板语言(VTL)
参考官网记录:https://velocity.apache.org/
基本符号
-
#
使用“#”用来标识Velocity的指令语句,比如:
#set
、#if
、#else
、#end
、#foreach
... -
$
访问Velocity变量使用$,比如:
$cosmic
。 -
!
变量名称前加上
!
,比如:$!cosmic
,如果cosmic
有值,将显示cosmic
的值,如果不存在就会显示为空白,一般会推荐使用。 -
|
访问引用时,可以设置默认值,而不是空白值:
My name is ${name|'John Doe'}
,name不存在时,会输出John Doe。
注释
单行注释:
## This is a single line comment.
多行注释:
#*
Thus begins a multi-line comment. Online visitors won't
see this text because the Velocity Templating Engine will
ignore it.
*#
文档注释:(VTL注释块)它可用于存储要在模板中跟踪的任何类型的额外信息(例如 javadoc 样式的作者和版本控制信息)
#**
This is a VTL comment block and
may be used to store such information
as the document author and versioning
information:
@author John Doe
@version 5
*#
变量(引用)
声明变量
变量始终以$
开头
// 定义变量`$a`
#set( $a = "Velocity" )
字符串用引号(单引号或双引号)括起来,单引号将确保将引用的值按原样分配给引用。双引号允许您使用Velocity引用和指令进行插值,例如 "Hello $name"
,其中$name
将替换为当前值,然后再将字符串文本分配给=
访问变量(Variables)
变量的简化形式由前导 $
字符后跟 VTL 标识符组成
$foo
$mudSlinger
$mud_slinger
$mudSlinger1
访问属性(Properties)
简化形式由一个前导$
字符后跟一个 VTL 标识符、后跟一个点字符 (“.”) 和另一个 VTL 标识符组成。以下是 VTL 中有效属性的示例:
$customer.Address
$purchase.Total
访问方法(Methods)
在 Java 代码中定义了一个方法,它能够执行一些有用的操作,例如运行计算或做出决策。
VTL 方法体由一个 VTL 标识符组成,后跟一个左括号字符 (“(”),后跟一个可选参数列表,后跟右括号字符 (“)”)。以下是 VTL 中有效方法引用的示例:
$customer.getAddress()
$purchase.getTotal()
$page.setTitle("My Home Page")
$person.setAttributes(["Strange", "Weird", "Excited"])
前两个示例$customer.getAddress()
和 $purchase.getTotal()
可能看起来类似于上面 Properties 部分中使用的示例,$customer.Address
和$purchase.Total
。如果您猜到这些示例必须以某种方式相关,那么您是对的!
注意
以$customer.Address
为例,它可以有两个含义。
这可能意味着,在标识为customer
的哈希表中查找,并返回与键Address
关联的值。
但$customer.Address
也可以指代方法:$customer.Address
可以是 $customer.getAddress()
的缩写方式。
当您的页面被请求时,Velocity 将确定这两种可能性中的哪一种有意义,然后返回适当的值。
总结:
VTL 属性可用作 VTL 方法的简写表示法。Property $customer.Address
与使用 Method $customer.getAddress()
的效果完全相同。
通常,最好使用 Property (如果可用)。Properties 和 Methods 之间的主要区别在于,您可以为 Method 指定参数列表。
数组
- 所有数组引用都被视为固定长度列表。这意味着您可以对数组引用调用
java.util.List
方法和属性。所以,如果你有一个对数组的引用(假设这个数组是一个具有三个值的 String[]),你可以这样做:
$myarray.isEmpty() or $myarray.empty
$myarray.size()
$myarray.get(2)
$myarray.set(1, 'test')
-
Velocity 还支持 vararg 方法。像下边的方法现在在模板中调用时可以接受任意数量的参数。
public void setPlanets(String... planets)
public void setPlanets(String[] planets)
$sun.setPlanets('Earth', 'Mars', 'Neptune')
$sun.setPlanets('Mercury')
$sun.setPlanets()## 只传递一个空的零长度数组
✨: 从 Velocity 2.0 开始,方法调用现在提供所有 Java 基本内置类型(数字、布尔值和字符串)之间的隐式转换。
属性查找规则
如前所述,属性通常引用父对象的方法。在确定哪个方法对应于请求的属性时,Velocity 非常聪明。它根据几个已建立的命名约定尝试不同的替代方案。确切的查找序列取决于属性名称是否以大写字母开头。对于小写名称(如$customer.address
),序列为
- getaddress()
- getAddress()
- get("address")
- isAddress()
- address() (从 Velocity 2.4 开始,以匹配 Java 16 记录字段 getter)
对于大写属性名称,如$customer.Address
,略有不同:
- getAddress()
- getaddress()
- get("Address")
- isAddress()
- Address()(从 Velocity 2.4 开始,以匹配 Java 16 记录字段 getter)
渲染
每个引用(无论是变量、属性还是方法)的最终值在呈现到最终输出时都会转换为 String 对象。如果存在表示 $foo 的对象(例如 Integer 对象),则 Velocity 将调用其.toString()
方法将对象解析为 String。
索引表示法(数组、Map)
使用 $foo[0] 形式的表示法可以用来访问对象的给定索引。这种形式与在给定对象上调用 get(Object) 方法同义,本质上是为此类操作提供了简化形式。由于这只是调用 get 方法,因此以下所有用途都是有效的:
$foo[0] ## $foo接受一个索引查询
$foo[$i] ## 使用另一个引用作为索引
$foo["bar"] ## 传递一个字符串,其中$foo可能是一个Map
代码块中的语法也适用于 Java 数组,因为 Velocity 将数组包装在一个访问对象中,该对象提供返回指定元素的get(Integer)
方法。
括号内的.get
语法在任何地方都有效,例如:
$foo.bar[1].junk
$foo.callMethod()[1]
$foo["apple"][4]
也可以使用索引表示法设置引用,例如:
#set($foo[0] = 1)
#set($foo.bar[1] = 3)
#set($map["apple"] = "orange")
指定的元素使用给定的值进行设置。Velocity 首先在元素上尝试 'set' 方法,然后 'put' 进行赋值。
正式引用表示法
上面列出的示例使用了参考文献的简化形式表示法,但也有参考文献的正式表示法,如下所示:
${mudSlinger}
${customer.Address}
${purchase.getTotal()}
在几乎所有情况下,您都会使用速记表示法作为引用,但在某些情况下,正确处理需要正式表示法。
需要正式表示法
假设您正在动态构建一个句子,其中$vice
将用作句子名词中的基词。目标是允许某人选择基本词并产生以下两个结果之一:“Jack is a pyromaniac.”或“Jack is a kleptomaniac.”。使用速记表示法对于此任务来说是不够的。请考虑以下示例:
Jack is a $vicemaniac.
这里存在歧义,Velocity 假定 $vicemaniac
而不是 $vice
是您要使用的属性。如果找不到$vicemaniac
的值,它将返回:$vicemaniac。使用正式表示法可以解决此问题。
Jack is a ${vice}maniac.
现在 Velocity 知道 $vice
而不是 $vicemaniac
是引用。当引用与模板中的文本直接相邻时,正式表示法通常很有用。
替代值用法(正式表示法)
当引用的布尔值为 false 时,正式引用表示法也可用于提供替代值。
My name is ${name|'John Doe'}