macro脚本元素允许模版设计者定义一段可以重复使用的VTL片断。不论简单的还是复杂的情况,Velocity宏都很有用。作为一个介绍Velocity宏的入门例子,下面的一段Velocity宏只有唯一的目的,就是减少打字的个数和可能发生的打字的错误。
macro( d ) #end
在这个例子中定义的宏的名字为d,并且可以使用类似于其他的VTL指示符的使用格式来调用:#d()
当这个模版被调用的时候,Velocity会使用一个空白的表格单元格来代替。
一个Velocity的宏能够包含零个(在上面这个例子中已经演示了)到任何个数的参数。但当Velocity宏在被调用的时候,调用的参数必须和这个宏在定义的时候定义的参数个数相同。当然,许多Velocity宏都比上面这个例子要复杂。下面是一个带有两个参数的Velocity宏的例子,一个颜色值,一个数组。
macro( tablerows colorsomelist )
foreach( somethinginsomelist )
end
end
这个叫做tablerows的Velocity宏带有两个参数。第一个参数代替了color的位置,第二个参数代替了somelist的位置。
任何的能放入模版中的VTL,都能放在Velocity宏中。tablerows包含了一个foreach语句,并且有两个#end语句。第一个数据#foreach,第二个结束了该Velocity宏的定义。
set( $greatlakes = [“Superior”,”Michigan”,”Huron”,”Erie”,”Ontario”] )
set( $color = “blue” )
注意greatlakes取代了somelist。当这个#tablerows象上面的例子那样调用,输出为:
Superior |
Michigan |
Huron |
Erie |
Ontario |
Velocity宏可以定义在一个Velocity模版之内,但这是意味在同一应用的其他的模版中该宏是不可见的。定义一个能让所有的模版都能使用的宏又很多的好处:能够减少定义同一个Velocity宏的数量,减少了出错的几率,并且保证了在一处的改变能应用到所有的模版中。
如果#tablerows(colorlist)定义在模版库中,那么这个宏就能在相似的所有的模版中使用了。它能被多次使用于不同的目标。在模版mushroom.vm中,调用#tablerows宏来列出一个典型的蘑菇房。
set( $parts = [“volva”,”stipe”,”annulus”,”gills”,”pileus”] )
set( $cellbgcol = “#CC00FF” )
#tablerows( cellbgcolparts )当完成了对mushroom.vm的请求,Velocity能在模版库中找到#tablerows宏——需要把这个宏定义在velocity.properties文件中。该例子输出为:
volva |
stipe |
annulus |
gills |
pileus |
Velocity宏中的参数Velocimacro Arguments
Velocity宏能有下列一些类型的VTL元素:
• 引用:Reference : anything that starts with ‘′∙字符串:Stringliteral:somethinglike“foo” or ‘hello’
• 数值:Number literal : 1, 2 etc
• 数值范围:IntegerRange : [ 1..2] or [foo..bar]
• 对象数组:ObjectArray : [ “a”, “b”, “c”]
• boolean value true
• boolean value false
当使用引用作为参数传递给Velocity宏,请注意引用是按名字使用。意味着他们的值是在Velocity宏中每一次的引用都是重新生成的。这个特点允许你传入一个对方法的引用,并且在宏中的每一次引用都调用该方法一次。作为一个例子,下面的代码展示了这一点:
macro( callme $a )
aa
$a
end
callme( $foo.bar() )
在callme宏中,方法引用foo.bar()实际上被调用了三次。resultsinthemethodbar()ofthereferencefoo being called 3 times.
初次接触该特性,会感到一些惊讶,但当你比较深入的思考Velocity宏的最初的动机的时候——减少在VTL中对于重复代码的剪切/复制操作。
如果你不需要这种特性,那么你可以总是把方法的值传递给一个变量引用,再把该引用作为参数传递给方法,如下面的例子所示:
set( myval=foo.bar() )
callme( $myval )
Velocity宏的属性Velocimacro Properties
在velocity.properties文件中有几行是用来控制Velocity的宏的。注意这部分在Developer Guide 中也有介绍。
velocimacro.library——以逗号分隔开的Velocity宏模版库的列表。默认情况下,Velocity只寻找VM_global_library.vm.这一个模版库。配制的模版路径用来寻找模版库。
velocimacro.permissions.allow.inline——取值为false或者true。该属性用来规定宏是否能定义在模版中。默认值为true,即允许模版设计者把宏直接定义在模版中。
velocimacro.permissions.allow.inline.to.replace.global——取值为true或者false。该属性规定在模版中定义的宏是否能覆盖在全局宏库(velocimacro.library)中定义的宏。该属性的默认值为false,即阻止定义在模版中的宏覆盖在引擎启动时候加载的全局宏。
velocimacro.permissions.allow.inline.local.scope - 取值为true或者false。该属性控制了在模版中定义的宏是否只对定义该宏的模版可见。