二、注釋 1.單行注釋: ## This is a single line comment. 2.多行注釋: #* Thus begins a multi-line comment. Online visitors won’t see this text because the Velocity Templating Engine will ignore it. *# 3.文檔格式: #** This is a VTL comment block and may be used to store such information as the document author and versioning information: @version 5 @author *#
作為一個使用VTL的頁面設計者,你和你的工程師必須就references的名稱達成共識,以便你可以在你的template中使用它們。 Everything coming to and from a reference被作為一個String對象處理。如果有一個對象$foo是一個Integer對象,那么Velocity將調用它的toString()方法將這個對象轉型為String類型。
4.正式reference標記 reference的正是格式如下: ${mudSlinger} 變量 ${customer.Address} 屬性 ${purchase.getTotal()} 方法 非正是格式更見常用,但是有時還是使用正是格式比較適合。例如:你希望通過一個變量$vice來動態的組織一個字符串。 Jack is a $vicemaniac. 本來變量是$vice現在卻變成了$vicemaniac,這樣Veloctiy就不知道您到底要什么了。所以,應該使用正是格式書寫 Jack is a ${vice}maniac 現在Velocity知道變量是$vice而不是$vicemaniac。
7.Case substitution 現在你已經對reference比較熟悉了,你可以將他們高效的應用于你的template了。Velocity利用了很多java規范以方便了設計人員的使用。例如: $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實例變量。
如果你的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
當一個web頁面被生成時使用Velocity的#if directrive,如果條件成立的話可以在頁面內嵌入文字。例如: #if ( $foo ) <strong>Velocity!</strong> #end 上例中的條件語句將在以下兩種條件下成立: l $foo是一個boolean型的變量,且它的值為true l $foo變量的值不為null 這里需要注意一點:Velocity context僅僅能夠包含對象,所以當我們說“boolean”時實際上代表的時一個Boolean對象。即便某個方法返回的是一個boolean值,Velocity也會利用內省機制將它轉換為一個Boolean的相同值。 如果條件成立,那么#if和#end之間的內容將被顯示。 #elseif和#else元素可以同#if一同使用。例如: #if( $foo < 10 ) <strong> Go North </strong> #elseif( $foo == 10 ) <strong> Go East </strong> #elseif( $foo == 6 ) <strong> Go South </strong> #else <strong> Go West </strong> #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
3.Velocity有AND、OR和NOT邏輯運算符。
下面是一些例子: ## logical AND #if( $foo && $bar ) <strong> This AND that </strong> #end
## logical OR #if ( $foo $bar ) <strong>This OR That </strong> #end
##logical NOT #if ( !$foo ) <strong> NOT that </strong> #end 4.循環 :Foreach循環
9.Velocimacro arguments Velocimacro可以使用以下任何元素作為參數: l Reference:任何以$開頭的reference l String literal: l Number literal: l IntegerRange:[1….3]或者[$foo….$bar] l 對象數組:[“a”,”b”,”c”] l boolean值:true、false
Velocity.properties文件中的某幾行能夠使Velocimacros的實現更加靈活。注意更多的內容可以看Developer Guide。 Velocity.properties文件中的velocimacro.libraary:一個以逗號分隔的模板庫列表。默認情況下,velocity查找唯一的一個庫:VM_global_library.vm。你可以通過配置這個屬性來指定自己的模板庫。 Velocity.properties文件中的velocimacro.permissions.allow.inline屬性:有兩個可選的值true或者false,通過它可以確定Velocimacros是否可以被定義在regular template內。默認值是ture――允許設計者在他們自己的模板中定義Velocimacros。 Velocity.properties文件中的 velocimacro.permissions.allow.inline.replace.global屬性有兩個可選值true和false,這個屬性允許使用者確定inline的Velocimacro定義是否可以替代全局Velocimacro定義(比如在velocimacro.library屬性中指定的文件內定義的Velocimacro)。默認情況下,此值為false。這樣就阻止本地Velocimacro定義覆蓋全局定義。 Velocity.properties文件中的 velocimacro.permissions.allow.inline.local.scale屬性也是有true和false兩個可選值,默認是false。它的作用是用于確定你inline定義的Velocimacros是否僅僅在被定義的template內可見。換句話說,如果這個屬性設置為true,一個inline定義的Velocimacros只能在定義它的template內使用。你可以使用此設置實現一個奇妙的VM敲門:a template can define a private implementation of the second VM that will be called by the first VM when invoked by that template. All other templates are unaffected。 Velocity.properties文件中的velocimacro.context.localscope屬性有true和false兩個可選值,默認值為false。當設置為true時,任何在Velocimacro內通過#set()對context的修改被認為是針對此velocimacro的本地設置,而不會永久的影響內容。 Velocity.properties文件中的velocimacro.library.autoreload屬性控制Velocimacro庫的自動加載。默認是false。當設置為ture時,對于一個Velocimacro的調用將自動檢查原始庫是否發生了變化,如果變化將重新加載它。這個屬性使得你可以不用重新啟動servlet容器而達到重新加載的效果,就像你使用regular模板一樣。這個屬性可以使用的前提就是resource loader緩存是off狀態(file.resource.loader.cache = false)。注意這個屬性實際上是針對開發而非產品的。 Velocimacro Trivia Velocimacro必須被定義在他們被使用之前。也就是說,你的#macro()聲明應該出現在使用Velocimacros之前。 特別要注意的是,如果你試圖#parse()一個包含#macro()的模板。因為#parse()發生在運行期,但是解析器在parsetiem決定一個看似VM元素的元素是否是一個VM元素,這樣#parse()-ing一組VM聲明將不按照預期的樣子工作。為了得到預期的結果,只需要你簡單的使用velocimacro.library使得Velocity在啟動時加載你的VMs。
11.Escaping VTL directives
VTL directives can be escaped with “/”號,使用方式跟VTL的reference使用逃逸符的格式差不多。 ## #include( “a.txt” ) renders as <ontents of a.txt>(注釋行) #include( “a.txt” )
Can I user a directive or another VM as an argument to a VM? 例如:#center ( #bold( “hello” ) ) 不可以。一個directive的參數使用另外一個directive是不合法的。 但是,還是有些事情你可以作的。最簡單的方式就是使用雙引號: #set ( $stuff = “#bold( ‘hello’ )” ) #center ( $stuff ) 上面的格式也可以縮寫為一行: #center ( “#bold( ‘hello’ ) ) 請注意在下面的例子中參數被evaluated在Velocimacro內部,而不是在calling level。例子: #macro ( inner $foo ) inner : $foo #end