- $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!