国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
《Velocity 模板使用指南》中文版
發(fā)表聲明:版權(quán)規(guī)文章原創(chuàng)作者所有
發(fā)表時(shí)間:2007年08月15日
發(fā)表作者:pablo3518
Velocity 模板使用指南》中文版
 
 
 
 
 
 
 
 
 
 
聲明: 轉(zhuǎn)載請(qǐng)保留此頁聲明
**************************************************************************
此文檔為藍(lán)杰實(shí)訓(xùn)學(xué)員拓展實(shí)訓(xùn)之用.
藍(lán)杰實(shí)訓(xùn)不對(duì)譯文中某些說法可能會(huì)對(duì)您的系統(tǒng)或開發(fā)造成損害負(fù)責(zé).
如對(duì)您有所幫助,我們不勝榮幸!
*************************************************************************
本文屬NetJava.cn中的Velocity中文系列,本系包含如下文章:
《Velocity Java開發(fā)指南中文版》(Developer`s Guide)
《Velocity模板使用指南中文版》(User`s Guide)
《Velocity Web應(yīng)用開發(fā)指南中文版》(Web Application Guide)
《VTL語法參考指南中文版》(VTL Reference)
《DB4O中文系列之起步篇》
 . . .
 更多資料請(qǐng)?jiān)L問http://www.netjava.cn/ 下載.
**************************************************************************
譯者: javaFound
*************************************************************************
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   
 
 
 
 
 
 
 
 
 
1.本文目地和使用對(duì)象
本文主要介紹如何在模板中使用Velocity功能強(qiáng)大的模板語言VTL(Velocity Template Language)用法有一個(gè)全面的認(rèn)識(shí),并掌握如何在模板中有效使用。同時(shí),本文提供較多的例子幫您來學(xué)習(xí)它.
感謝您選擇Velocity幫助您實(shí)現(xiàn)純正的MVC系統(tǒng)構(gòu)架。
2.什么是Velocity?
Velocity 是一個(gè)基于java的模板引擎(template engine). 它可以讓視圖的設(shè)計(jì)者在web頁面中引用java代碼中定義的數(shù)據(jù)對(duì)象和命令。從而使Web designers和java開發(fā)者依照MVC思想(Model-View-Controller )開發(fā)系統(tǒng),這意味著Web designers只須將精力注用于良好表現(xiàn)力的視圖外觀設(shè)計(jì),而Java程序員則只要關(guān)心著如何寫出高效簡(jiǎn)潔的java對(duì)象以實(shí)現(xiàn)業(yè)務(wù)邏輯-----Velocity會(huì)將他們組裝到一起. 相比傳統(tǒng)的jsp、PHP等腳本語言,Velocity徹底的將避免了在視圖設(shè)計(jì)中出現(xiàn)的java代碼, 從而保證了web site的長(zhǎng)期可維護(hù)性.
一定要理解,Velocity是一個(gè)template engine的意思,它還可以從模板中生成SQL語句或其它腳本提供給web pages. 它也可以獨(dú)立使用---做為一個(gè)工具類(utility class)用來生成源代碼、報(bào)表、郵件模板等---在有需要重復(fù)的視圖情況下,你應(yīng)想到使用Velocity.Apache站點(diǎn)提供的另外一個(gè)框架Turbine 可以和Velocity有效結(jié)合以實(shí)現(xiàn)true MVC model.
3.Velocity能為你做什么?
1.一個(gè)Mud Store Example
假設(shè)你是一個(gè)page designer 在為一個(gè)在線商店設(shè)計(jì)頁面. 我們稱這個(gè)項(xiàng)目為 "The Online Mud Store".業(yè)務(wù)發(fā)展還不錯(cuò),客戶會(huì)訂購不同類型的MuD,每個(gè)客戶都會(huì)用自己的賬號(hào)密碼login,查看選擇他們訂購的MuD,查看訂單,但還有些忠誠用戶會(huì)購賣不太流行的MuD----這些不需要出現(xiàn)在頁面中顯眼的地方。當(dāng)然,The Online MuD Store必須把每個(gè)客戶資料及訂購信息記錄到DB中,現(xiàn)在的問題是,如何讓某個(gè)客戶login后就看到他感興趣的信息?
使用Velocity!我們?yōu)槊總€(gè)客戶定制一個(gè)頁面!這聽起來工作量巨大,讓我們?cè)囋嚕?
使用Velocity的 VTL 如下來設(shè)計(jì) web page:
<HTML>
<BODY>
##指定用戶名字
歡迎你: $customer.Name!
<table>
###輸出用戶喜好的MuD
#foreach( $mud in $mudsOnSpecial )
   #if ( $customer.hasPurchased($mud) )
      <tr>
        <td>
          $flogger.getPromo( $mud )
        </td>
      </tr>
   #end
#end
</table>
使用VTL設(shè)計(jì)頁面就是這么簡(jiǎn)單!文檔《VTL參考中文版》中有更全面的VTL語言介紹,掌握這些,你將會(huì)全面體會(huì)到Velocity的威力.
4.Velocity Template Language (VTL): 介紹
The Velocity Template Language (VTL)目標(biāo)是提供一個(gè)簡(jiǎn)潔,易學(xué)的方法將動(dòng)態(tài)內(nèi)容展現(xiàn)到web page上. a web page設(shè)計(jì)者可以沒有任何編程經(jīng)驗(yàn)就可以在一天內(nèi)學(xué)會(huì)使用它增強(qiáng)你的站點(diǎn)的展示力!.
VTL使用引用(references )這種方式將dynamic content(動(dòng)態(tài)內(nèi)容,一般指java代碼生成的數(shù)據(jù)對(duì)象)加入到你的web site,Velocity中的變量(variable)只是refernce中的一種. Variables是用來描述從引入到視圖模板中的java數(shù)據(jù)對(duì)象。當(dāng)然,java代碼也可以從模板的VTL中獲取數(shù)據(jù).以下是一個(gè)寫在HTML中的VTL變量:
#set( $a = "Velocity" )
VTL聲明( statement),所以的VTL statement都是以#開頭,且包含一個(gè)指示符(這里是set),當(dāng)客戶訪問你的頁面時(shí), the Velocity Templating Engine將搜索頁面中的所有 # 符號(hào),如果確定這是一個(gè)VTL聲明時(shí)就按一定規(guī)則處理動(dòng)態(tài)內(nèi)容, 符號(hào)#僅僅只是表明這可能是一個(gè)VTL聲明.
符號(hào)# 所跟的set我們用“指示符”這一名詞來稱呼它(隨后介紹更多的指示符), set 指示符使用一個(gè)表達(dá)式(expression) (包含在一對(duì)括號(hào)里) –將一個(gè)值 value (這里是Velocity)付給變量a,(變量名在左邊,值在右邊,用=組合起來).
在以上的例子中,變量是a ,而符號(hào)“$”表明它是一個(gè)變量,Velocity中所有變量以符號(hào)”$”開頭,所付的值要用雙引號(hào)括起, 這個(gè)值中還可以再添加Velocity變量,如"Hello $name",輸出的將是name變量所付的值。
這是理解VTL基礎(chǔ)的規(guī)則:
 以$開頭的表示“引用”意思是取得一些東東.而”指示”(Directives)則以#開頭來表示,有點(diǎn)“做些什么動(dòng)作”的意思.
如上便, #set 用來指定值給一個(gè)變量名$a, 以“$”標(biāo)示的變量名a的值就是"Velocity".
5.輸出第一個(gè)VTL頁面!
有你的HTML文檔的任何地方,都可以引用一個(gè)變量名來輸出值, 如下例, 先給變量名foo 賦值為Velocity,然后將它輸出到頁面中.
<html>
<body>
 
#set( $foo = "Velocity" )
Hello $foo World!
</body>
<html>
在這個(gè)頁面上,你看到的將是 "Hello Velocity World!".
為了讓查板中的VTL指令更易讀, 我們強(qiáng)烈建議你每行一條VTL指令,當(dāng)然這不是必須的. 關(guān)于 set directive的更多功能我們隨后再討論.
6.Comments(注釋)
Comments可以讓你在模板中包含對(duì)VTL或其它問題的說明描述以便與閱讀和理解.---但它并不會(huì)在最終輸出的web pages中看到.如下示例是VTL中的一行注釋.
## This is a single line comment.
單行注釋是以## 開頭的一行文字.如要寫下多行注釋,就要像下面那樣,將它們放入#**#間:
This is text that is outside the multi-line comment.
Online visitors can see it.
 
#*
 Thus begins a multi-line comment. Online visitors won‘t
 see this text because the Velocity Templating Engine will
 ignore it.
*#
 
不需要太復(fù)雜了,這兩種方式己足夠你給自己的頁面加上充分的說明。
7.References(引用)
VTL中有三種references:變量引用(variables),屬性引用(properties)和命令引用(methods). 做為一個(gè)使用VTL的設(shè)計(jì)者, 你和你的java軟件工程師必須就模板中引用的特定名了(就是$后的名字)達(dá)成一致的協(xié)議!這樣,模板和java代碼才可按照你們的意圖去結(jié)合以輸出正確的內(nèi)容.
所有的引用在模板中都表現(xiàn)為一個(gè)字符串. 假設(shè)一個(gè)引用變量 $foo 的值事實(shí)上是一個(gè)int, Velocity engine在處理時(shí)將調(diào)用它的.toString() 去解析這個(gè)字符串所代表的對(duì)象(int).
1.Variables(變量)
簡(jiǎn)單的說變量以"$" 開后,后面跟一個(gè)VTL指示符( Identifier).一個(gè)合法的VTL指示符是以字母開頭,后面可以是以下任意字符:
alphabetic (a .. z, A .. Z)
numeric (0 .. 9)
hyphen ("-")
underscore ("_")
以下是正確的VTL變量名:
$foo
$mudSlinger
$mud-slinger
$mud_slinger
$mudSlinger1
當(dāng)VTL中的一個(gè)變量如 $foo, 這個(gè)變量可以在模板中提取它自己的值通過set 指示符,或者從java代碼中.比如,如果需java中的變量foo的值為bar,給模板中所有輸出$foo聲明的值都成為bar.當(dāng)然,在模板中使用如下VTL也可以達(dá)到這個(gè)目地。
#set( $foo = "bar" )
2.Properties(屬性)
VTL的第二種引用,屬性引用,注意”屬性”具有相對(duì)固定的格式. 它也是以$開頭的合法VTL指示符,隨后是”變量名字.變量屬性”. 如下例:
$customer.Address
$purchase.Total
第一個(gè)例子, $customer.Address.我們?cè)O(shè)想可能在兩種意思.首先它可能在查找customer引用的一個(gè)hashtable中的以“Address”為key關(guān)聯(lián)的一個(gè)數(shù)據(jù)對(duì)象.另外他可能表示的是java對(duì)象customer中的getAddress()這個(gè)命令取得的結(jié)果(當(dāng)然也可寫成 $customer.getAddress()). 當(dāng)客戶請(qǐng)求Web頁面中Velocity將根據(jù)具體的customer類型輸出.
3.Methods(命令)
在java 代碼中定義命令是最通常的事, 像執(zhí)得一組方程式計(jì)算成本,讀取一個(gè)文件等. 命令引用和其它引用一個(gè)也是一個(gè)一般的VTL聲明,看如下的例子可能會(huì)更快的理解:
$customer.getAddress()
$purchase.getTotal()
$page.setTitle( "My Home Page" )
$person.setAttributes( ["Strange", "Weird", "Excited"] )
前兩個(gè)例子 -- $customer.getAddress() and $purchase.getTotal() – 可以等同與屬性引用情況: $customer.Address and $purchase.Total. 如你猜對(duì)了這點(diǎn),呵,你還蠻聰明!同時(shí),他們是等同與java對(duì)象coustomer的getAddress()命令調(diào)用。后面兩個(gè)引用呢,也會(huì)直接對(duì)應(yīng)java對(duì)象的對(duì)應(yīng)命令,不同的是傳入了命令參數(shù)。
4.屬性引用中的屬性查找規(guī)則
前己提及,屬性可以引用到對(duì)象的命令. Velocity會(huì)使用合適的策略選擇引用到的命令. 它會(huì)根據(jù)協(xié)定的命令命令格式查找. 無論屬性引用的的名字是否大小寫,Velocity都有固定的查找規(guī)則.如在$customer.address引用時(shí),查找順序是:
  1. getaddress()
  2. getAddress()
  3. get("address")
  4. isAddress()
對(duì)于VTL中大寫的屬性名Address引用,將是:
  1. getAddress()
  2. getaddress()
  3. get("Address")
  4. isAddress()
8.Formal Reference Notation(正規(guī)引用格式注意事項(xiàng))
以上是簡(jiǎn)潔格式引用的介紹,規(guī)則的格式像下面,如你看到的變量名需要放到{}中:
${mudSlinger}
${customer.Address}
${purchase.getTotal()}
大多數(shù)情況下,簡(jiǎn)潔格式引用足以滿足使用,但有些情況下,必須使用正規(guī)格式引用.
假設(shè)你構(gòu)造的一個(gè)字符串中要包括有 $vice 變量的值. 你覺得以下兩種寫法會(huì)是同樣的結(jié)果嗎:
1.Jack is a $vicemaniac.
2.Jack is a ${vice}maniac.
這樣,Velocity就知你要的是 $vice, 而不是 $vicemaniac變量,正規(guī)引用格式一般用于在模板中直接調(diào)整字符串內(nèi)容.
9.Quiet Reference Notation(靜態(tài)引用輸出)
Velocity遇到一個(gè)不能處理的引用時(shí),一般他會(huì)直接輸出這個(gè)引用$email的寫法,頁面上會(huì)看到的是$email,如下例,我們可以在$后面加上一個(gè)!號(hào),那么就會(huì)輸出空白:.
<input type="text" name="email" value="$email"/>
 
<input type="text" name="email" value="$!email"/>
正式的寫法是:.
<input type="text" name="email" value="$!{email}"/>
10.Getting literal( 語義問題)
一般情況下,velocity使用$,#字符來標(biāo)志它的聲明,但有時(shí),HTML中因?yàn)槟撤N其它意圖,也會(huì)寫出這樣的字符,我們討論如何消除這種語義歧義問題.
1.Currency(貨幣標(biāo)志)
如美元 $2.50!這樣的寫法出現(xiàn)到模板中, VTL處理時(shí)是不會(huì)出錯(cuò),會(huì)正確的輸出$2.50!這個(gè)你想要的結(jié)果。為什么呢?一個(gè)合法的VTL標(biāo)示符是以一個(gè)字母開頭的,我們前面己說過.
2.Escaping Valid VTL References(封裝有效的引用)
如下示,如果沒有#set( $email = "foo" )這一行且java代碼中Context對(duì)象中沒有放放email對(duì)象,將直接輸出$email.
#set( $email = "foo" )
$email
如果email己定義了 (比如它的值是 foo),而這里你卻想輸出 $email. 這樣一個(gè)字符串,就需要使用轉(zhuǎn)義字符”\”.
## The following line defines $email in this template:
#set( $email = "foo" )
$email
\$email
\\$email
\\\$email
上面的模板在web頁面上的輸出將是:
foo
$email
\foo
\$email
但如果email并沒有定義,我們這樣寫:.
$email
\$email
\\$email
\\\$email
輸出就原封不動(dòng)了:
$email
\$email
\\$email
\\\$email
注意:當(dāng)己定義變量和未定義變量一起輸出時(shí),會(huì)輸出字面意思,如下便,$moon是未定義的:
#set( $foo = "gibbous" )
$moon = $foo
輸出到web頁面中將是
 $moon = gibbou
11.Case Substitution(可選的格式)
至此,你對(duì)velocity的refenerce己比較熟悉了, 你可以在你的模板中開始應(yīng)用這些功能. 但你還可以知道的是Velocity references從java語法中汲取了一些優(yōu)點(diǎn)以便模板設(shè)計(jì)者更容易使用VTL.比如:
$foo
 
$foo.getBar()
## 等同于
$foo.Bar
 
$data.setUser("jon")
##等同于
#set( $data.User = "jon" )
 
$data.getRequest().getServerName()
##等同于
$data.Request.ServerName
## is the same as
${data.Request.ServerName}
這里示例了你可選的一些引用方式. VTL汲取了java語法和java bean的一些簡(jiǎn)潔語法以解析java代碼中Context中的對(duì)象和這些對(duì)象的命令及屬性---這樣,一個(gè)java對(duì)象的所有功能都可以展示到視圖中了.
Velocity也借見了java Bean的規(guī)范(Bean specifications defined by Sun Microsystems), 是大小寫敏感的; 但Velocity會(huì)盡可能的幫你修正錯(cuò)誤. 當(dāng)命令 getFoo() 通過指令 $bar.foo在模板中引用時(shí),Velocity的搜索規(guī)則我們?cè)谇懊婕褐v了,你還記得是什么嗎?.
注意:模板中引用的必須是通過java Bean中的getter/setter 實(shí)現(xiàn)的,而直接的java對(duì)象的數(shù)據(jù)域是不能直接引用的,如$foo.Name 會(huì)解析到 class Foo‘s getName() 的實(shí)例方法,但不會(huì)解析到Foos類的 public Name 這個(gè)實(shí)例變量.
12.Directives(指令符號(hào))
模板設(shè)計(jì)者使用“引用“生成動(dòng)態(tài)內(nèi)容, 指令(directives) – 簡(jiǎn)單的說就是設(shè)計(jì)者在模板中操作java對(duì)象—讓視圖設(shè)計(jì)者全面控制輸出內(nèi)容的格式.
指令總是以 #開頭后面緊跟具體的指令符. 就像引用一樣(指令的一種),可以將指令理解為”表示這里是一個(gè)什么東東).如下例生成一個(gè)出錯(cuò)提示:
#if($a==1)true enough#elseno way!#end
這個(gè)例子中應(yīng)使用括號(hào)將else分開.
#if($a==1)true enough#{else}no way!#end
1.#set指令
#set 用來給一個(gè)引用賦值.值可以被賦給變量引用或?qū)傩砸? 但要將它們放入括號(hào)中,如下示:
#set( $primate = "monkey" )
#set( $customer.Behavior = $primate )
“左操作數(shù)被賦值“是引用操作的一個(gè)規(guī)則.=號(hào)右側(cè)可能是以下類型之一:
  • Variable reference變量引用
  • String literal字符串
  • Property reference 屬性引用
  • Method reference 命令引用
  • Number literal 數(shù)字
  • ArrayList 數(shù)組
  • Map 映射
下面是對(duì)上述類型設(shè)置的示例:
#set( $monkey = $bill ) ## variable reference
#set( $monkey.Friend = "monica" ) ## string literal
#set( $monkey.Blame = $whitehouse.Leak ) ## property reference
#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference
#set( $monkey.Number = 123 ) ##number literal
#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList
#set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## Map
注意: 在ArrayList類型引用的例子中,其原素定義在數(shù)組 [..]中, 因此,你可以使表 $monkey.Say.get(0)訪問第一個(gè)元素.
類似的,引用Map 的例子中, 原素定義在 { } 中,其鍵和值間以:隔成一對(duì),使用 $monkey.Map.get("bannana") 在上例中將返回 ‘good‘, ( $monkey.Map.banana也會(huì)有同樣效果).
下面是一般的計(jì)算表達(dá)式:
#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )
但注意:如果右邊的操作數(shù)是一個(gè)屬性或命令的引用而返回null,那么賦值將不會(huì)成功,且在隨后的VTL中也不能再取出使用. 如下例:
#set( $result = $query.criteria("name") )
The result of the first query is $result
 
#set( $result = $query.criteria("address") )
The result of the second query is $result
如果 $query.criteria("name") 返回的是字符串 "bill", 但 $query.criteria("address") 返回null, 上面的TVL輸出結(jié)果將是:
The result of the first query is bill
 
The result of the second query is bill
這對(duì)與初學(xué)者的理解有些麻煩,比如在 #foreach loops中, 你使用 #set 給一個(gè)屬性或命令賦值時(shí),如下例示:
 
#set( $criteria = ["name", "address"] )
 
#foreach( $criterion in $criteria )
 
    #set( $result = $query.criteria($criterion) )
 
    #if( $result )
        Query was successful
    #end
 
#end
在上例中,就不能依賴if( $result )來決定查詢是否成功. $result 一但被 #set 為null (context會(huì)同樣), 它將不能被賦 其它值 (不能從 context中取出).
一個(gè)解決辦法是,每次都將$result 設(shè)為 false. 如果 $query.criteria() 調(diào)用成功,就可以檢測(cè)到.
 
#set( $criteria = ["name", "address"] )
 
#foreach( $criterion in $criteria )
 
    #set( $result = false )
    #set( $result = $query.criteria($criterion) )
 
    #if( $result )
        Query was successful
    #end
 
#end
注意: #set 不需要使用 #end 來聲明結(jié)尾.
2.Literals (語義解析)
使用#set 指令時(shí),變量如果用 “”引起會(huì)被解析,如:
#set( $directoryRoot = "www" )
#set( $templateName = "index.vm" )
#set( $template = "$directoryRoot/$templateName" )
$template
輸出的將是:
www/index.vm
但當(dāng)用單引號(hào)引起來時(shí),就不會(huì)被解析::
#set( $foo = "bar" )
$foo
#set( $blargh = ‘$foo‘ )
$blargh
輸出后會(huì)是:
 bar
 $foo
默認(rèn)情況下,不會(huì)解析單引號(hào)中的變量,當(dāng)然,這可以通過改變Velocity的配置參數(shù)來改變:
velocity.properties such that stringliterals.interpolate=false.
另外, 指令 #literal 元素可以用來輸出字面意思,如下示.
#literal()
#foreach ($woogie in $boogie)
 nothing will happen to $woogie
#end
#end
會(huì)輸出::
#foreach ($woogie in $boogie)
 nothing will happen to $woogie
#end
3.Conditionals(條件判斷)
1.If / ElseIf / Else
#if 指令用來根據(jù)條件在頁面中輸出內(nèi)容, 如下簡(jiǎn)單的例子:
#if( $foo )
   <strong>Velocity!</strong>
#end
根據(jù)變量 $foo計(jì)算后是否為true決定輸出, 這會(huì)有兩種情況: (i) $foo 的是值是一個(gè)boolean (true/false)型并有一個(gè)true value, 或 (ii) 它是一個(gè)非null值. 要記者,Velocity context 中只能包含Objects, 因此當(dāng)我們講 ‘boolean‘時(shí), 它就是一個(gè)Boolean (the class).
#if#end 的內(nèi)容是否會(huì)輸出,由$foo是否為true決定. 這里,如果 $foo is true, 輸出將是: "Velocity!". 如果$foo 為null或false,將不會(huì)有任何輸出.
#elseif#else 可以 #if 和組合使用. 如果第一個(gè)表達(dá)式為true,將會(huì)不計(jì)算以后的流程,如下例假設(shè)t $foo 是15 and $bar 產(chǎn) 6.
#if( $foo < 10 )
    <strong>Go North</strong>
#elseif( $foo == 10 )
    <strong>Go East</strong>
#elseif( $bar == 6 )
    <strong>Go South</strong>
#else
    <strong>Go West</strong>
#end
輸出將會(huì)是
Go South.
2.Relational and Logical Operators(關(guān)系和邏輯運(yùn)算)
Velocity使用==來做比較,如下例.
#set ($foo = "deoxyribonucleic acid")
#set ($bar = "ribonucleic acid")
 
#if ($foo == $bar)
 In this case it‘s clear they aren‘t equivalent. So...
#else
 They are not equivalent and this will be the output.
#end
注意:== 計(jì)算與java中的 == 計(jì)算有些不同:不能用來測(cè)試對(duì)象是否相等(指向同一塊內(nèi)存). Velocity中是否相等僅直接的用來比較numbers, strings的值, or objects的toString()結(jié)果是否相等. 如果是不同的對(duì)象,會(huì)調(diào)用它們的toString()命令結(jié)果來比較.
Velocity也使用AND, OR and NOT 執(zhí)行邏輯運(yùn)算.詳細(xì)說明請(qǐng)參看《VTL參考中文版》,如下是一些簡(jiǎn)單示例:
## logical AND
 
#if( $foo && $bar )
   <strong> This AND that</strong>
#end
 
僅當(dāng) $foo $bar 和都為true時(shí),#if()才會(huì)輸出中間內(nèi)容.
OR 運(yùn)算例子
## logical OR
 
#if( $foo || $bar )
    <strong>This OR That</strong>
#end
$foo或$bar只要有一個(gè)為true就可以輸出。
NOT運(yùn)算則只有一個(gè)操作參數(shù)或表達(dá)式 :
 
##logical NOT
 
#if( !$foo )
 <strong>NOT that</strong>
#end
 
考慮下,下面的例子有幾種輸出結(jié)果?.
#if( $foo == $bar)it‘s true!#{else}it‘s not!#end</li>
4.Loops(循環(huán))
Foreach Loop
#foreach 用來創(chuàng)建循環(huán). For example:
<ul>
#foreach( $product in $allProducts )
    <li>$product</li>
#end
</ul>
#foreach 會(huì)生成包含$products中對(duì)象的一個(gè)列表. 每一次循環(huán)都會(huì)將列表中的一個(gè)對(duì)象賦與變量$product .
 $allProducts 或以是一個(gè)Vector, a Hashtable or an Array類型的容器. 指定給變量 $product 是一個(gè)引用到其中一個(gè)java對(duì)象的引用. For example, if $product 確實(shí)是一個(gè)java代碼中的Product class i,它可以這樣的方法訪問$product.Name method (ie: $Product.getName()).
我們假設(shè) $allProducts 是一個(gè)Hashtable.看看取出其中的東東多么簡(jiǎn)單:
<ul>
#foreach( $key in $allProducts.keySet() )
    <li>Key: $key -> Value: $allProducts.get($key)</li>
#end
</ul>
通過引用變量$velocityCount可以訪問到Velocity提供的計(jì)數(shù)器:
<table>
#foreach( $customer in $customerList )
    <tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end
</table>
$velocityCount默認(rèn)的計(jì)數(shù)器引用,你可以在配置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
當(dāng)然,你還可以設(shè)置其它參數(shù),具體見《Velocity Java開發(fā)指南中文版》中講解.
# The maximum allowed number of loops.
directive.foreach.maxloops = -1
3.Include(引入)
#include 腳本元素讓模板設(shè)計(jì)者可以在模板中引入一個(gè)本地文件, 這個(gè)被引入的文件將不會(huì)經(jīng)過Velocity的解析. 安全起見,可以引放的文件只是是配置參數(shù)TEMPLATE_ROOT所定義目錄下的,默認(rèn)為當(dāng)前目錄下.
#include( "one.txt" )
如果需要引入多個(gè)文件,可以像下面這樣.
#include( "one.gif","two.txt","three.htm" )
當(dāng)然,還可用一個(gè)變量名來代替文件名引入.
#include( "greetings.txt", $seasonalstock )
6.Parse(解析模板)
#parse 元素指示可以引入一個(gè)包含TVL的本地文件,這個(gè)文件將被Veloict engine解析輸出。.
#parse( "me.vm" )
#include 指令不同, #parse 可以從引入的模板中得到變量引用.但#parse指令只能接受一個(gè)參數(shù).
VTL templates 被#parse 的模板中還可以再包含#parse聲明,默認(rèn)的深度為10,這是由配置參數(shù)directive.parse.max.depth在文件velocity.properties中決定的,你可以修改它以適合項(xiàng)目要求
7.Stop
#stop 指令用來指示在模板的某處,engine停止解析,這一般用來調(diào)用。用法很簡(jiǎn)單.
#stop
8.Velocimacros(宏調(diào)用)
#macro 指令讓模板設(shè)計(jì)者可以將些重復(fù)、相關(guān)的的腳本版斷定義為一個(gè)功能塊.無論在什么情況下. 出于單一意圖設(shè)計(jì)的 Velocimacro都會(huì)最大程序的減少模板編寫中可以的出錯(cuò),還是看個(gè)例子來理解一下Velocimacros的概念.
#macro( d )
<tr><td></td></tr>
#end
這樣就定義了一個(gè)名為d的宏,它可以在其它的模板中像下面那樣直接引用:
#d()
Velocimacro可以接收0到任意多的傳入?yún)?shù).如上個(gè)例是0個(gè)參數(shù),但當(dāng)它被調(diào)用時(shí),也必須傳入同樣多的參數(shù). 這里定義了一個(gè)有兩個(gè)參數(shù)的宏.
#macro( tablerows $color $somelist )
#foreach( $something in $somelist )
    <tr><td bgcolor=$color>$something</td></tr>
#end
#end
然后,我們?cè)陧撁嬷衼硎褂茫?
#set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] )
#set( $color = "blue" )
<table>
    #tablerows( $color $greatlakes )
</table>
注意變量 $greatlakes 取代了宏中變量 $somelist的輸出,最終的輸出如下:
<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>
宏一般被定義在模板中,那么站點(diǎn)上的其它模板中又如何調(diào)用呢?如能定義一個(gè)可以更大范圍內(nèi)共想的宏就太好了
如果將宏#tablerows($color $list) 定義到一個(gè)模板庫中(Velocimacros template library), 其它模板就都可以訪問它了.
Velocimacro Arguments(宏的參數(shù))
Velocimacros可以從TVL中接受以下參數(shù) :
  • 引用類型 : 所有以‘$‘開頭的
  • String literal : something like "$foo" or ‘hello‘
  • Number literal : 1, 2 etc
  • IntegerRange : [ 1..2] or [$foo .. $bar]
  • ObjectArray : [ "a", "b", "c"]
  • boolean value true
  • boolean value false
當(dāng)傳一個(gè)引用參數(shù)給宏時(shí), 引用是通過名字傳入的(‘pass by name‘).
     #macro( callme $a )
         $a $a $a
     #end
 
     #callme( $foo.bar() )
  
上例中命令 bar() 被調(diào)用了3 times.
最后要說的是,這個(gè)特性有些難以學(xué)習(xí),但當(dāng)你精心組織規(guī)劃你的宏庫時(shí), 消除在VTL中重復(fù)功能的腳本時(shí) –你可以像使用一個(gè)對(duì)象或組件一樣使用宏, 比如一個(gè)宏對(duì)象生成多個(gè)表格的重復(fù)色彩.
如果你想利用這個(gè)特性,你只需要像下面那樣簡(jiǎn)單的編碼傳一個(gè)值給它來調(diào)用 :
     #set( $myval = $foo.bar() )
     #callme( $myval )
  
Velocimacro Properties(宏的屬性)
配置文件 velocity.properties 中有多行相關(guān)配置,具體請(qǐng)見《Velocity Java開發(fā)指南中文版》.
velocimacro.library –用來指定全局的宏庫,多個(gè)可以,號(hào)分開.
velocimacro.permissions.allow.inline – 默認(rèn)為true,可以讓宏定義在一個(gè)正規(guī)的模板文件中.
velocimacro.permissions.allow.inline.to.replace.global – 用來指定模板內(nèi)定義的宏的功能是否要以替換全局庫,默認(rèn)為false.
velocimacro.permissions.allow.inline.local.scope –模板中定義的宏的使用范圍是否只是本模板可用.
velocimacro.context.localscope –如果為true,宏通過#set賦值時(shí).宏中將保持一個(gè),且不會(huì)由于context中的數(shù)據(jù)被修改而變化,同樣,宏中的修改也不會(huì)改變context中的。
velocimacro.library.autoreload – 是否自動(dòng)重新載入,用于調(diào)試環(huán)境,默認(rèn)false,如為true,需要取掉chcheing:. file.resource.loader.cache = false ).
一些細(xì)節(jié):
宏必須在模板中使用#macro()指令前定義.
盡量不要直接在模板中使用#parse() 包含 #macro() 指令.因?yàn)?#parse() 動(dòng)作在運(yùn)行時(shí)執(zhí)行,時(shí)會(huì)有一個(gè)在VM中查找元素的過程.
13.注掉 VTL Directives
嗯,你學(xué)下英語吧,一看就懂J
VTL directives can be escaped with the backslash character ("\") in a manner similar to valid VTL references.
## #include( "a.txt" ) renders as <contents of a.txt>
#include( "a.txt" )
 
## \#include( "a.txt" ) renders as #include( "a.txt" )
\#include( "a.txt" )
 
## \\#include ( "a.txt" ) renders as \<contents of a.txt>
\\#include ( "a.txt" )
Extra care should be taken when escaping VTL directives that contain multiple script elements in a single directive (such as in an if-else-end statements). Here is a typical VTL if-statement:
#if( $jazz )
    Vyacheslav Ganelin
#end
If $jazz is true, the output is
Vyacheslav Ganelin
If $jazz is false, there is no output. Escaping script elements alters the output. Consider the following case:
\#if( $jazz )
    Vyacheslav Ganelin
\#end
Whether $jazz is true or false, the output will be
 #if($ jazz )
     Vyacheslav Ganelin
 #end
 
In fact, because all script elements are escaped, $jazz is never evaluated for its boolean value. Suppose backslashes precede script elements that are legitimately escaped:
\\#if( $jazz )
   Vyacheslav Ganelin
\\#end
In this case, if $jazz is true, the output is
\ Vyacheslav Ganelin
\
To understand this, note that the #if( arg ) when ended by a newline (return) will omit the newline from the output. Therefore, the body of the #if() block follows the first ‘\‘, rendered from the ‘\\‘ preceding the #if(). The last \ is on a different line than the text because there is a newline after ‘Ganelin‘, so the final \\, preceding the #end is part of the body of the block.
If $jazz is false, the output is
\
Note that things start to break if script elements are not properly escaped.
\\\#if( $jazz )
    Vyacheslave Ganelin
\\#end
Here the #if is escaped, but there is an #end remaining; having too many endings will cause a parsing error.
14.VTL: 一般使用的格式
盡量是這樣:
#set( $imperial = ["Munetaka","Koreyasu","Hisakira","Morikune"] )
#foreach( $shogun in $imperial )
    $shogun
#end
而不要這樣寫,雖然它可以運(yùn)行:
Send #set($foo=["$10 and ","a pie"])#foreach($a in $foo)$a#end please.
Velocity會(huì)自動(dòng)跳過空格,上面的可以這樣寫::
Send me
#set( $foo = ["$10 and ","a pie"] )
#foreach( $a in $foo )
$a
#end
please.
or as
Send me
#set($foo       = ["$10 and ","a pie"])
                 #foreach           ($a in $foo )$a
         #end please.
In each case the output will be the same.
15.Other Features and Miscellany(其它特性和細(xì)節(jié))
1.數(shù)學(xué)計(jì)算
如下是四則運(yùn)算的例子:
#set( $foo = $bar + 3 )
#set( $foo = $bar - 4 )
#set( $foo = $bar * 6 )
#set( $foo = $bar / 2 )
2.Range Operator
The range operator can be used in conjunction with #set and #foreach statements. Useful for its ability to produce an object array containing integers, the range operator has the following construction:
[n..m]
Both n and m must either be or produce integers. Whether m is greater than or less than n will not matter; in this case the range will simply count down. Examples showing the use of the range operator as provided below:
First example:
#foreach( $foo in [1..5] )
$foo
#end
 
Second example:
#foreach( $bar in [2..-2] )
$bar
#end
 
Third example:
#set( $arr = [0..1] )
#foreach( $i in $arr )
$i
#end
 
Fourth example:
[1..3]
Produces the following output:
First example:
1 2 3 4 5
 
Second example:
2 1 0 -1 -2
 
Third example:
0 1
 
Fourth example:
[1..3]
Note that the range operator only produces the array when used in conjunction with #set and #foreach directives, as demonstrated in the fourth example.
Web page designers concerned with making tables a standard size, but where some will not have enough data to fill the table, will find the range operator particularly useful.
3.Advanced Issues: Escaping and !
When a reference is silenced with the ! character and the ! character preceded by an \ escape character, the reference is handled in a special way. Note the differences between regular escaping, and the special case where \ precedes ! follows it:
#set( $foo = "bar" )
$\!foo
$\!{foo}
$\\!foo
$\\\!foo
This renders as:
$!foo
$!{foo}
$\!foo
$\\!foo
Contrast this with regular escaping, where \ precedes $:
\$foo
\$!foo
\$!{foo}
\\$!{foo}
This renders as:
$foo
$!foo
$!{foo}
\bar
4.Velocimacro Miscellany(關(guān)于宏的一些問題)
這是一些簡(jiǎn)短的問題總結(jié),也許你先要有這樣一個(gè)概念:. ‘Velocimacro‘ 就像一個(gè)‘VM’。
可否用一個(gè)指示符做為另外一個(gè)指示符運(yùn)算的參數(shù)?
如 : #center( #bold("hello") )
No. 指示符不是有效的參數(shù)但你可以這樣實(shí)現(xiàn)你想要的:
#set($stuff = "#bold(‘hello‘)" )
#center( $stuff )
或者:
#center( "#bold( ‘hello‘ )" )
上面這個(gè)例子中,參數(shù)是在調(diào)用的宏中生成的.不是調(diào)用者傳入的. 看看下面的例子 :
 
#macro( inner $foo )
 inner : $foo
#end
 
#macro( outer $foo )
   #set($bar = "outerlala")
   outer : $foo
#end
 
#set($bar = ‘calltimelala‘)
#outer( "#inner($bar)" )
 
輸出將是:
Outer : inner : outerlala
因?yàn)?"#inner($bar)" 是發(fā)生在 #outer()內(nèi)部的!
可否通過 #parse()來注冊(cè)一個(gè)宏 ?
宏必須在模板使用前定義好.前面己有一個(gè)關(guān)于此問題的建議,#parse()是運(yùn)行時(shí)執(zhí)進(jìn)的,JVM查找對(duì)象的順序不一定會(huì)全按我們預(yù)計(jì)的執(zhí)行。
什么是宏的自動(dòng)重新裝載?
這是由配置參數(shù)決定的, 為方例開發(fā)者,在生產(chǎn)環(huán)境中則不需要 :
velocimacro.library.autoreload
默認(rèn)的是false.當(dāng)設(shè)為true中,需要設(shè)定chcheing參數(shù);
<type>.resource.loader.cache = false
(具體配置請(qǐng)見開發(fā)指南,如下是一個(gè)配置的例子)
    file.resource.loader.path = templates
    file.resource.loader.cache = false
    velocimacro.library.autoreload = true
   
注意:Don‘t keep this on in production.
5.String Concatenation(連結(jié)字符串)
很簡(jiǎn)單,看例子就是 :
       #set( $size = "Big" )
       #set( $name = "Ben" )
 
      The clock is $size$name.
  
上面的輸出將是
 ‘The clock is BigBen‘.
或者:
      #set( $size = "Big" )
      #set( $name = "Ben" )
 
      #set($clock = "$size$name" )
 
      The clock is $clock.
   
它們都是同樣的輸出,最后一個(gè)例子如下,:
      #set( $size = "Big" )
      #set( $name = "Ben" )
 
      #set($clock = "${size}Tall$name" )
 
      The clock is $clock.
   
輸出將是
 ‘The clock is BigTallBen‘.
16.Feedback
如果您有什么問題或建議,請(qǐng)聯(lián)系 Velocity developers list. Thanks!
 
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
CHAPTER 3 Velocity介紹 - Velocity空間 - BlogJava
Velocity(8)——引入指令和#Stop指令
FreeMarker vs. Velocity
愛創(chuàng)課堂 前端培訓(xùn) 前端教程 angular教程 課堂筆記
每個(gè)人應(yīng)該知道的NVelocity用法
接口,id,繼承
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服