閱讀204 返回首頁    go 阿裏雲 go 技術社區[雲棲]


NVelocity介紹

一、NVelocity介紹

1.1  Velocity是什麼

nVelocity是一個基於.NET的模板引擎(template engine)。它允許任何人僅僅簡單的使用模板語言(template language)來引用由.NET代碼定義的對象。

nVelocity 應用於web開發時,界麵設計人員可以和.NET程序開發人員同步開發一個遵循MVC架構的web站點,也就是說,頁麵設計人員可以隻關注頁麵的顯示效果,而由.NET程序開發人員關注業務邏輯編碼。nVelocity.NET代碼從web頁麵中分離出來,這樣為web站點的長期維護提供了便利,同時也為我們在aspx之外又提供了一種可選的方案。

nVelocity的能力遠不止web站點開發這個領域,例如,它可以從模板(template)產生SQLPostScriptXML,它也可以被當作一個獨立工具來產生源代碼和報告,或者作為其他係統的集成組件使用。nVelocity也可以為很多web開發架構提供模板服務(template service)。我們的係統就提供一個模板服務的方式允許一個web應用以一個真正的MVC模型進行開發。

1.2 nVelocity能為我們作什麼?

假設你是一家專門出售Mud的在線商店的頁麵設計人員,讓我們暫且稱它為“在線MUD商店”。你們的業務很旺,客戶下了各種類型和數量的Mud訂單。他們都是通過輸入用戶名和密碼後才登陸到你的網站,登陸後就允許他們查看訂單並購買更多的Mud。現在,一種非常流行的mud正在打折銷售。另外有一些客戶規律性的購買另外一種也打折但不是很流行的Bright Red Mud,由於購買的人並不多所以它被安置在頁麵的邊緣。所有用戶的信息都是被跟蹤並存放於數據庫中的,所以某天有一個問題可能會冒出來:為什麼不使用nVelocity來使用戶更好的瀏覽他們感興趣的商品呢? 

nVelocity使得web頁麵的客戶化工作非常容易。作為一個站點的設計人員,你希望每個用戶登陸時都擁有自己的頁麵。 

你會見了一些公司內的軟件工程師,你發現他們每個人都同意客戶應該擁有具有個性化的信息。那讓我們把軟件工程師應該作的事情放在一邊,看一看你應該作些什麼吧。

你可能在頁麵內嵌套如下的VTLnVelocity template language)聲明: 

<html>

<body>

Hello $customer.Name!

<table>

#foreach( $mud in $nudsOnSpecial )

#if ( $customer.hasPurchased( $mud ) )

<tr><td>$flogger.getPromo( $mud )</td></tr>

#end

#end

</table>

1.1 VTL (nVelocity template language)

VTL意味著提供最簡單、最容易並且最整潔的方式合並頁麵動態內容。 VTL 使用references來在站點內嵌套動態內容,一個變量就是一種類型的reference。變量是某種類型的reference,它可以指向.NET代碼中的定義,或者從當前頁麵內定義的VTL statement得到值。下麵是一個VTL statement的例子,它可以被嵌套到 HTML代碼中:

#set ( $a = “Velocity” )

和所有的VTL statement一樣,這個statement以#字符開始並且包含一個directiveset。當一個在線用戶請求你的頁麵時,nVelocity Template Engine將查詢整個頁麵以便發現所有#字符,然後確定哪些是VTL statement,哪些不需要VTL 作任何事情。 

#字符後緊跟一個directiveset時,這個set directive使用一個表達式(使用括號封閉)將一個值設置給變量。變量被列在左邊,而它的值被列在右邊,最後他們之間使用=號分割。

在上麵的例子中,變量是$a,而它的值是Velocity。和其他的references一樣以$字符開始,而值總是以雙引號封閉。Velocity中僅有String可以被賦值給變量。

記住以下的規則: 

使用$字符開始的references用於得到什麼;使用#字符開始的directives用於作些什麼。

1.2 Hello nVelocity World

一旦某個變量被分配了一個值,那麼你就可以在HTML文件的任何地方引用它。在下麵的例子中,一個值被分配給$foo變量,並在其後被引用。 

<html> 

<body> 

#set ( $foo = “nVelocity” ) 

Hello $foo World! 

</body> 

</html> 

上麵的實現結果是在頁麵上打印“Hello nVelocity World!”

為了使包含VTL directivesstatement更具有可讀性,我們鼓勵你在新行開始一個VTL statement,盡管你不是必須這麼作。Set directive將在後麵詳細描述。


1.1 注釋

單行注釋:

 ## This is a single line comment.

多行注釋: 

 #* 

   Thus begins a multi-line comment. Online visitors won’t

   see this text because the Velocity Template Engine will ignore it.

 *# 

文檔格式: 

 #** 

   This is a VTL comment block and 

   may be used to store such information as the document author

and versioning information: 

   @version 5 

   @author 

 *# 

1.2 References

VTL中有三種類型的references:變量(variables)、屬性(properties)、方法 (methods)。作為一個使用VTL的頁麵設計者,你和你的工程師必須就references的名稱達成共識,以便你可以在你的template中使用它們。

VTL中一切reference可以作為一個String對象處理。如果有一個對象$foo是一個Integer對象,那麼Velocity將調用它的toString()方法將這個對象轉型為String類型。

1.2.1 變量

格式要求同.NET

1.1.1 屬性

例子:

$customer.Address

$purchase.Total

$customer.Address有兩種含義。它可以表示:查找hashtable對象customer中以Address為關鍵字的值;也可以表示調用customer對象的 getAddress()方法。當你的頁麵被請求時,Velocity將確定以上兩種方式選用那種,然後返回適當的值。

1.1.2 方法

一個方法就是被定義在.NET中的一段代碼,並且它有完成某些有用工作的能力,例如一個執行計算和判斷條件是否成立、滿足等。方法是一個由$開始並跟隨VTL標識符組成的References,一般還包括一個VTL方法體。例如:

$customer.getAddress()

$purchase.getTotal()

$page.setTitle( “My Home Page” )

$person.setAttributes( [“Strange”, “Weird”, “Excited”] )

前兩個例子$customer.getAddress()$purchase.getTotal()看起來挺想上麵的屬性$customer.Address  $purchase.Total。如果你覺得他們之間有某種聯係的話,那你是正確的。

VTL屬性可以作為VTL方法的縮寫。$customer.Address屬性和使用$customer.getAddress()方法具有相同的效果。如果可能的話使用屬性的方式是比較合理的。屬性和方法的不同點在於你能夠給一個方法指定一個參數列表。

1.1.1 正式reference標記

reference正式格式如下:

${mudSlinger}變量

${customer.Address}屬性

${purchase.getTotal()}方法

正式格式更見常用,但是有時還是使用正是格式比較適合。例如:你希望通過一個變量$vice來動態的組織一個字符串。

Jack is a $vicemaniac.

本來變量是$vice現在卻變成了$vicemaniac,這樣Veloctiy就不知道您到底要什麼了。所以,應該使用正是格式書寫

Jack is a ${vice}maniac

現在Velocity知道變量是$vice而不是$vicemaniac

1.1.2 Quiet reference notation

如:

<input type=”text” name=”email” value=”$email” />

當頁麵的form被初始加載時,變量$email還沒有值,這時你肯定是希望它能夠顯示一個空白來代替輸出”$email”這樣的字段。那麼使用quiet reference notation就比較合適。

<input type=”text” name=”email” value=”$!email”/>

這樣文本框的初始值就不會是email而是空值了。

正式和quiet格式的reference notation也可一同使用,像下麵這樣:

<input type=”text” name=”email” value=”$!{email}”/>


1.1.1 Getting literal

nVelocity使用特殊字符$#來幫助它工作,所以如果要在template裏使用這些特殊字符要格外小心。本節將討論$字符。

VTL中使用$2.5這樣的貨幣標識是沒有問題得的,VTL不會將它錯認為是一個reference,因為VTL中的reference總是以一個大寫或者小寫的字母開始。

VTL中使用“"”作為轉義字符。

例如:

#set( $email = “foo” )

$email

"$email

""$email

"""$email

將輸出為:

foo

$email

"foo

""$email

如果email變量沒有被定義則

$email

"$email

""$email

"""$email

將被輸出為:

$email

"$email

""$email

"""$email

注意:VTL中未被定義的變量將被認為是一個字符串,所以以下例子:

#set( $foo = “gibbous” )

$moon = $foo

的輸出結果是:

$moon = gibbous

現在你已經對reference比較熟悉了,你可以將他們高效的應用於你的template了。nVelocity利用了很多.NET規範以方便了設計人員的使用。例如:

$foo

$foo.getBar()

##與下麵這句相同

$foo.Bar

$data.getUser(“john”)

##與下麵這句相同

$data.User(“john”)

$data.getRequest().getServerName()

#與下麵這句相同

$data.Request.ServerName

##與下麵這句相同

${data.Request.ServerName}

但是,注意VTL中不會將reference解釋為對象的實例變量。例如:$foo.Name將被解釋為Foo對象的getName()方法,而不是Foo對象的Name實例變量。


1.1 Directives

Reference允許設計者使用動態的內容,而directive使得你可以應用.NET代碼來控製你的顯示邏輯,從而達到你所期望的顯示效果。

1.1.1 賦值#set

#set directive被用於設置一個reference的值。例如:

#set ( $primate = “monkey” )

#set ( $customer.Behavior = $primate )

賦值左側的(LHS)必須是一個變量或者屬性reference。右側(RHS)可以是以下類型中一種:

變量reference

字符串

屬性reference

方法reference

數字

ArrayList

下麵是應用各種類型的RHS的例子:

set ( $monkey = $bill ) ##變量reference

set ( $monkey.Friend = “monica” ) ##字符串

set ( $monkey.Blame = $whitehouse.Leak ) ##屬性reference

set ( $monkey.Plan = $spindoctor.weave($web) ) ##方法reference

set ( $monkey.Number = 123 ) ##數字

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是一個nullVTL的處理將比較特殊:它將指向一個已經存在的reference,這對初學者來講可能是比較費解的。例如:

#set ( $resut = $query.criteria(“name”) )

結果是$result

#set ( $resut = $query.criteria(“address”) )

結果是$result

如果$query.criteria(“name”)返回一個“bill”,而$query.criteria(“address”)返回的是null,則顯示的結果如下:

結果是bill

結果是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),它不能被設置回nullremoved 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

1.1.1 字符串

當你使用#set directive,字符串封閉在一對雙引號內。

#set ( $directoryRoot = “www” )

#set ( $templateName = “index.vm” )

#set ( $template = “$directoryRoot/$tempateName” )

$template

上麵這段代碼的輸出結果為:www/index.vm

但是,當字符串被封裝在單引號內時,它將不被解析:

#set ( $foo = “bar” )

$foo

#set ( $blargh = ‘$foo' )

結果:

bar

$foo

上麵這個特性可以通過修改Views目錄下的nvelocity.properties文件的stringliterals.interpolate = false的值來改變上麵的特性是否有效。

1.1.2 條件語句

if/elseif/else

當一個web頁麵被生成時使用Velocity#if directrive,如果條件成立的話可以在頁麵內嵌入文字。例如:

#if ( $foo )

<strong>nVelocity!</strong>

#end

上例中的條件語句將在以下兩種條件下成立:

$foo是一個boolean型的變量,且它的值為true

$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

注意這裏的nVelocity的數字是作為Integer來比較的――其他類型的對象將使得條件為false,它使用==來比較兩個值,而且nVelocity要求等號兩邊的值類型相同。

最後更新:2017-04-03 18:52:11

  上一篇:go java 可重啟線程及線程池類的設計
  下一篇:go Android 向多媒體數據庫增加音頻文件