- $foo
- $foo.getBar()
- ## is the same as
- $foo.Bar
- $data.getUser(“jon”)
- ## is the same as
- $data.User(“jon”)
- $data.getRequest().getServerName()
- # is the same as
- $data.Request.ServerName
- ## is the same as
- ${data.Request.ServerName}
但是, 注意VTL中不会将reference解释为对象的实例变量。例如:$foo.Name将被解释为Foo对象的getName()方法,而不是Foo对象的Name实例变量。
Directives(google translate:指令)
Reference允许设计者使用动态的内容,而directive使得你可以应用java代码来控制你的显示逻辑,从而达到你所期望的显示效果。
#set
#set directive被用于设置一个reference的值。例如:
#set ( $primate = “monkey” )
#set ( $customer.Behavior = $primate )
赋值左侧的(LHS)必须是一个变量或者属性reference。右侧(RHS)可以是以下类型中一种:
l 变量reference
l String literal
l 属性reference
l 方法reference
l number literal
l ArrayList
下面是应用各种类型的RHS的例子:
- #set ( $monkey = $bill ) ##变量reference
- #set ( $monkey.Friend = “monica” ) ##String literal
- #set ( $monkey.Blame = $whitehouse.Leak )##属性reference
- #set ( $monkey.Plan = $spindoctor.weave($web) )##方法reference
- #set ( $monkey.Number = 123 )##Number literal
- #set ( $monkey.Say = [“Not”, $my, “fault”] )##ArrayList
注意:最后一个例子的取值方法为:$monkey.Say.get(0)
RHS也可以是一个简单的算术表达式:
- #set ( $value = $foo + 1 )
- #set ( $value = $bar -1 )
- #set ( $value = $foo * $bar )
- #set ( $value = $foo / $bar )
如果你的RHS是一个null,VTL的处理将比较特殊:它将指向一个已经存在的reference,这对初学者来讲可能是比较费解的。例如:
#set ( $resut = $query.criteria(“name”) )
The result of the first query is $result
#set ( $resut = $query.criteria(“address”) )
The result of the second query is $result
如果$query.criteria(“name”)返回一个“bill”,而$query.criteria(“address”)返回的是null,则显示的结果如下:
The result of the first query is bill
The result of the first query is bill
看看下面的例子:
- #set( $criteria = ["name", "address"] )
- #foreach( $criterion in $criteria )
- #set( $result = $query.criteria($criterion) )
- #if( $result )
- Query was successful
- #end
- #end
在上面的例子中,程序将不能智能的根据$result的值决定查询是否成功。在$result被#set后(added to the context),它不能被设置回null(removed from the context)。打印的结果将显示两次查询结果都成功了,但是实际上有一个查询是失败的。
为了解决以上问题我们可以通过预先定义的方式:
- #set( $criteria = [“name”, “address”] )
- #foreach( $criterion in $criteria )
- #set( $result = false )
- #set( $result = $query.criteria( $criterion ) )
- #if( $result )
- Query was successful
- #end
- #end
- String Literals
当你使用#set directive,String literal封闭在一对双引号内。
#set ( $directoryRoot = “www” )
#set ( $templateName = “index.vm” )
#set ( $template = “$directoryRoot/$tempateName” )
$template
上面这段代码的输出结果为:www/index.vm
但是,当string literal被封装在单引号内时,它将不被解析:
#set ( $foo = “bar” )
$foo
#set ( $blargh = ‘$foo’ )
结果:
bar
$foo
上面这个特性可以通过修改velocity.properties文件的stringliterals.interpolate = false的值来改变上面的特性是否有效。
条件语句
if/else if/else
当一个web页面被生成时使用Velocity的#if directrive,如果条件成立的话可以在页面内嵌入文字。例如:
#if ( $foo )
Velocity!
#end
上例中的条件语句将在以下两种条件下成立:
l $foo是一个boolean型的变量,且它的值为true
l $foo变量的值不为null
这里需要注意一点:Velocity context仅仅能够包含对象,所以当我们说“boolean”时实际上代表的时一个Boolean对象。即便某个方法返回的是一个boolean值,Velocity也会利用内省机制将它转换为一个Boolean的相同值。
如果条件成立,那么#if和#end之间的内容将被显示。
#elseif和#else元素可以同#if一同使用。例如:
#if( $foo < 10 )
Go North
#elseif( $foo == 10 )
Go East
#elseif( $foo == 6 )
Go South
#else
Go West
#end
注意这里的Velocity的数字是作为Integer来比较的――其他类型的对象将使得条件为false,但是与java不同它使用“==”来比较两个值,而且velocity要求等号两边的值类型相同。
关系、逻辑运算符
Velocity中使用等号操作符判断两个变量的关系。例如:
#set ( $foo = “deoxyribonucleic acid” )
#set ( $bar = “ribonucleic acid” )
#if ( $foo == $foo )
In this case it’s clear they aren’t equivalent.So…
#else
They are not equivalent and this will be the output.
#end
Velocity有AND、OR和NOT逻辑运算符。下面是一些例子:
## logical AND
#if( $foo && $bar )
This AND that
#end
## logical OR
#if ( $foo || $bar )
This OR That
#end
##logical NOT
#if ( !$foo )
NOT that
#end
循环
Foreach循环
例子:
- <ul>
- #foreach ( $product in $allProducts )
- <li> $product </li>
- #end
- </ul>
每次循环$allProducts中的一个值都会赋给$product变量。
$allProducts可以是一个Vector、Hashtable或者Array。分配给$product的值是一个java对象,并且可以通过变量被引用。例如:如果$product是一个java的Product类,并且这个产品的名字可以通过调用他的getName()方法得到。
现在我们假设$allProducts是一个Hashtable,如果你希望得到它的key应该像下面这样:
- <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默认的名字,你也可以通过修改velocity.properties文件来改变它。默认情况下,计数从“1”开始,但是你可以在velocity.properties设置它是从“1”还是从“0”开始。下面就是文件中的配置:
# Default name of loop counter
# variable reference
directive.foreach.counter.name = velocityCount
# Default starting value of the loop
# counter variable reference
directive.foreach.counter.initial.value = 1
include
#include script element允许模板设计者引入本地文件。被引入文件的内容将不会通过模板引擎被render。为了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目录下。
#inclued ( “one.txt” )
如果您需要引入多个文件,可以用逗号分隔就行:
#include ( “one.gif”, “two.txt”, “three.htm” )
在括号内可以是文件名,但是更多的时候是使用变量的:
#inclue ( “greetings.txt”, $seasonalstock )
parse
#parse script element允许模板设计者一个包含VTL的本地文件。Velocity将解析其中的VTL并render模板。
#parse( “me.vm” )
就像#include,#parse接受一个变量而不是一个模板。任何由#parse指向的模板都必须包含在TEMPLATE_ROOT目录下。与#include不同的是,#parse只能指定单个对象。
你可以通过修改velocity.properties文件的parse_direcive.maxdepth的值来控制一个template可以包含的最多#parse的个数――默认值是10。#parse是可以递归调用的,
例如:如果dofoo.vm包含如下行:
Count down.
- #set ( $count = 8 )
- #parse ( “parsefoo.vm” )
- All done with dofoo.vm!
那么在parsefoo.vm模板中,你可以包含如下VTL:
- $count
- #set ( $count = $count – 1 )
- #if ( $count > 0 )
- #parse( “parsefoo.vm” )
- #else
- All done with parsefoo.vm!
- #end
的显示结果为:
Count down.
8
7
6
5
4
3
2
1
0
All done with parsefoo.vm!
All done with dofoo.vm!