1.1. Foreach 循环
#foreach 元素允许进行循环,例如:
<ul> #foreach( $product in $allProducts ) <li>$product</li> #end </ul> |
这个#foreach 循环将导致$allProducts 列表 (对象) 为查询所有的产品$products (目标)遍历一遍。每次经过循环,从$allProducts 取得的值将置于$product 变量之中。
$allProducts 变量的内容是一个矢量,一个哈希表或者数组。赋给$product 变量的值是一个Java 对象并且可以从一个类似的变量引用。例如,如果 $product 真是一个Java的产品类,其名称可以通过引用$product.Name 方法来检索(即: $Product.getName())。
我们假定 $allProducts 是一个哈希表。如果你想检索关键字的值或者在哈希表中的对象,你可以使用以下的代码:
<ul> #foreach( $key in $allProducts.keySet() ) <li>Key: $key -> Value: $allProducts.get($key)</li> #end </ul> |
Velocity 提供一个更容易的方式或的循环计数,以便你可以做下面类似的工作:
<table> #foreach( $customer in $customerList ) <tr><td>$velocityCount</td><td>$customer.Name</td></tr> #end </table> |
循环计数变量的缺省名称是$velocityCount, 在velocity.properties 配置文件中标明。默认情况下,该变量从1开始计数,但是可以在velocity.properties 文件中设为从0或者1开始。 下面是velocity.properties 文件中循环变量设置一节:
# Default name of the loop counter # variable reference. directive.foreach.counter.name = velocityCount
# Default starting value of the loop # counter variable reference. directive.foreach.counter.initial.value = 1 |
2. 包含
#include 脚本元素允许模板设计人员包含(导入)本地文件, 这个文件将插入到#include 指令被定义的地方。文件的内容并不通过模板引擎来渲染。处于安全的原因,被包含的文件只可以放在TEMPLATE_ROOT下。
#include( "one.txt" ) |
#include 指令引用的文件在双引号内。如果超过一个文件,其间用逗号隔开。
#include( "one.gif","two.txt","three.htm" ) |
被包含的文件并不是一定要用文件名来引用,事实上,最好的办法是使用变量而不是文件名。这在根据规则决定何时提交页面时,决定目标输出是很有用的。
#include( "greetings.txt", $seasonalstock ) |
3. 解析
#parse 脚本元素允许页面设计员导入包含VTL的本地文件。 Velocity将解析和渲染指定的模板。
#parse( "me.vm" ) |
就象 #include 指令,#parse 可以使用变量而不是一个实在的模板文件。#parse 引用的模板文件必须包含的TEMPLATE_ROOT指定的目录之下。和 #include 指令不一样, #parse 只有一个参数。
VTL 模板templates can have #parse statements referring to templates that in turn have #parse statements. By default set to 10, the parse_directive.maxdepth line of the velocity.properties allows users to customize maximum number of #parse referrals that can occur from a single template. (Note: If the parse_directive.maxdepth property is absent from the velocity.properties file, Velocity will set this default to 10.) Recursion is permitted, for example, if the template dofoo.vm contains the following lines:
Count down. #set( $count = 8 ) #parse( "parsefoo.vm" ) All done with dofoo.vm! |
It would reference the template parsefoo.vm, which might contain the following VTL:
$count #set( $count = $count - 1 ) #if( $count > 0 ) #parse( "parsefoo.vm" ) #else All done with parsefoo.vm! #end |
After "Count down." is displayed, Velocity passes through parsefoo.vm, counting down from 8. When the count reaches 0, it will display the "All done with parsefoo.vm!" message. At this point, Velocity will return to dofoo.vm and output the "All done with dofoo.vm!" message.
4. 停止
#stop 脚本允许模板设计员停止模板引擎的执行,并返回。这通常用作调试。
#stop |
1. 宏
#macro 脚本元素允许模板设计者在VTL 模板中定义重复的段。 Velocimacros 不管是在复杂还是简单的场合都非常有用。下面这个Velocimacro,仅用来节省击键和减少排版错误,介绍了一些Velocity宏的概念。
#macro( d ) <tr><td></td></tr> #end |
在例子中,Velocimacro定义为d,它可以象调用其他VTL指令一样的形式来进行调用:
#d() |
当这个模板被调用时, Velocity 将 #d() 替换为一个单行的空表格。
Velocimacro 可以带一些参数,也可以不带参数(如上例所示)。但在他被调用时,所带的参数必须和其定义时的参数一样。很多Velocimacros 定义为不止一个参数。下面这个宏带有两个参数,一个颜色,一个数组。
#macro( tablerows $color $somelist ) #foreach( $something in $somelist ) <tr><td bgcolor=$color>$something</td></tr> #end #end |
在这个例子中定义的Velocimacro,名为tablerows, 要求两个参数。 第一个参数代替$color, 第二个代替$somelist。
可以写进VTL 模板中的东西都可以写进Velocimacro 的主体部分。tablerows 宏其实是一个foreach 语句。在#tablerows 宏的定义中有两个#ende语句,第一个属于#foreach, 第二个结束宏定义。
#set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] ) #set( $color = "blue" ) <table> #tablerows( $color $greatlakes ) </table> |
请注意$greatlakes 替换了$somelist。 这样,当#tablerows 宏被调用时,将产生以下输出:
<table> <tr><td bgcolor="blue">Superior</td></tr> <tr><td bgcolor="blue">Michigan</td></tr> <tr><td bgcolor="blue">Huron</td></tr> <tr><td bgcolor="blue">Erie</td></tr> <tr><td bgcolor="blue">Ontario</td></tr> </table> |
Velocimacros 在Velocity 模板语句内定义,这意味着它在同一站点内的其他Velocity 模板中并不有效。定义一个宏,并使其与其他模板共享很具有明显的优点:他减少了在大量的模板内重复定义宏的工作,并减少了出错的机会,并确保对其他宏的改 变对其他所有模板有效。
但如果 #tablerows($color $list) 宏是在一个Velocimacros 模板库内定义的,它就可以被其他常规模板所用。当然,它可以用于各种目的,也可重用多次。在表示所有真菌类(fungi)的mushroom.vm 模板中,#tablerows 宏可以被用来列出典型的蘑菇。
#set( $parts = ["volva","stipe","annulus","gills","pileus"] ) #set( $cellbgcol = "#CC00FF" ) <table> #tablerows( $cellbgcol $parts ) </table> |
我们对mushroom.vm执行请求,Velocity 将在模板库内找到#tablerows 宏 (在velocity.properties 文件中定义)并产生以下输出:
<table> <tr><td bgcolor="#CC00FF">volva</td></tr> <tr><td bgcolor="#CC00FF">stipe</td></tr> <tr><td bgcolor="#CC00FF">annulus</td></tr> <tr><td bgcolor="#CC00FF">gills</td></tr> <tr><td bgcolor="#CC00FF">pileus</td></tr> </table> |
Velocimacro 参数
Velocimacros 的参数可以是以下的VTL元素:
引用(Reference): 以 '$' 打头的元素
字面字符串(String literal) : 比如"$foo" 或 'hello'
字面数字: 1, 2 ….
整数范围: [ 1..2] 或 [$foo .. $bar]
对象数组: [ "a", "b", "c"]
布尔真
布尔假
当把引用作为参数传递给Velocimacros时,请注意引用是按“名字”传递的。这意味着他们的值在每次使用他们的Velocimacro中产生。这个特性允许你在方法调用是传递引用,并在每次使用时进行方法调用。例如,Fo,当调用下面的Velocimacro 时,
#macro( callme $a ) $a $a $a #end
#callme( $foo.bar() ) |
结果是,在方法bar() 中,引用 $foo 被调用了3次。
咋看时,这个特征让人吃惊,当当你考虑一下Velocimacros的原本动机 – 在VTL模板中避免很多“剪切复制”操作—你就会明白。它允许你将无状态对象,比如在一个颜色表格行内重复产生一些颜色次序的对象,传递给Velocimacro。
如果你需要使用这个特征,你通常可以从方法内取得一个值,作为一个新的引用传递给宏:
#set( $myval = $foo.bar() ) #callme( $myval ) |