Velocity宏定義的坑與解決辦法

使用Velocity,固然就免不了要使用宏,或者說使用Velocity而不使用其宏,就至關於廢了Velocity一半以上的武功,很是惋惜的。 html

怎麼使用Velocity的宏呢,才最大程度的發揮其做用可是又避免掉入其中的坑呢?且聽悠然亂彈亂彈: 框架

官方文檔中,關於Macro是這麼說的: ui

#macro - Allows users to define a Velocimacro (VM), a repeated segment of a VTL template, as required

Format: spa

# [ { ] macro [ } ] ( vmname $arg1 [ $arg2 $arg3 ... $argn ] ) [ VM VTL code... ] # [ { ] #end [ } ] scala

  • vmname - Name used to call the VM (#vmname)
  • $arg1 $arg2 [ ... ] - Arguments to the VM. There can be any number of arguments, but the number used at invocation must match the number specified in the definition.
  • [ VM VTL code... ] - Any valid VTL code, anything you can put into a template, can be put into a VM.

Once defined, the VM is used like any other VTL directive in a template. code

#vmname( $arg1 $arg2 )

固然,上面清晰的說明了怎麼寫Macro,

也就是說能夠寫成: orm

#{macro}(macroName $varName1 $varName2)

##這裏是模板內容

#end
也能夠寫成
#macro(macroName $varName1 $varName2)

##這裏是模板內容

#end
固然參數個數能夠是0..n個。

OK,確實很簡單,可是上面的說法實際上只解決了如何寫出知足正確語法的宏,可是實際應用當中,若是不加以約束,可能就出現很是難以查找的問題。 htm

好比下面定義了一個超連接的宏,因爲id不是每次都用獲得,所以id是可選參數,能夠填,也能夠不填: 圖片

#macro(link $href $id)
<a href="$!href"#if($id) id="$id"#end>$bodyContent</a>
#end
而後,就能夠以下使用了:
#@link("www.tinygroup.com")TinyGroup#end

上面的寫法有問題麼??彷佛沒有什麼問題,即便什麼參數也不傳,只寫下面的調用方法: ci

#@link()#end
渲染的結果也會是:
<a href=""></a>
OK,如此說來,真的沒有啥問題。

接下來,咱們又要寫一個圖片連接的宏,一樣的因爲id不是每次都須要,咱們把它寫成可選的:

#macro(image $href $id)
<img src="$href"#if($id) id="$id"#end>
#end
在調用的時候,咱們能夠以下寫:
#image("www.tinygroup.org/img/logo.gif")
也能夠這樣寫
#image("www.tinygroup.org/img/logo.gif" "logoImage")
OK,一切都沒有什麼問題

可是咱們想給首頁上的Logo圖片加個連接到首面上。

這個時候,咱們會以下寫:

#@link("www.tinygroup.org")
#image("www.tinygroup.org/img/logo.gif")
#end
渲染的結果也如咱們所指望的
<a href="www.tinygroup.org"><img src="www.tinygroup.org/img/logo.gif"></a>
確實也如咱們指望,正確的渲染了。

這個時候,咱們突然指望首頁連接添加個id,指望利用JQuery對其進行一些動態處理,咱們就把代碼寫成下面的樣子:

#@link("www.tinygroup.org" "homepageLink")
#image("www.tinygroup.org/img/logo.gif")
#end
這個時候,咱們去執行的時候,突然發現,程序不能正確運行了,去查看一下渲染的最終結果,竟然是:
<a href="www.tinygroup.org" id="homepageLink"><img src="www.tinygroup.org/img/logo.gif"  id="homepageLink"></a>
這說明一個道理就是:
  • 外層的宏中的變量,在內層的宏中是能夠訪問的
  • 內層中的變量,若是與外層中宏的變量名衝突,若是有傳入,則按傳入的值,若是沒有傳入,則取上層中的值

正是基於上述緣由,在Tiny UI框架中,全部宏定義,宏變量都必須前宏前綴,也就是說上面的兩個宏定義要按下面的方式來進行定義:

#macro(link $linkHref $linkId)
<a href="$!linkHref"#if($linkId) id="$linkId"#end>$bodyContent</a>
#end
#macro(image $imageHref $imageId)
<img src="$imageHref"#if($imageId) id="$imageId"#end>
#end

小結:

雖然緣由及解決辦法都很是簡單,可是也是吃了虧以後才總結出來的,但願能對也使用Velocicty或其它模板語言的同窗有幫助。

相關文章
相關標籤/搜索