轉自:http://fhd001.iteye.com/blog/1167764
freemarker之模板開發(其它之自定義指令)
----------
自定義指令可以使用macro指令來定義,這是模板設計者所關心的內容。Java程序員若不想在模板中實現自定義指令,而是在java語言中實現指令的定義,這時可以使用:freemarker.template.TemplateDirectiveModel類來擴展。
? ?
宏
宏是有一個變量名的模板片段。你可以在模板中使用宏作為自定義指令,這樣就能進行重復性的工作。
如例:
- <#macro?greet>??
- ????<font?size="+2">Hello?Joe!</font>??
- </#macro>??
macro指令自身不打印任何內容,它只是用來創建宏變量,所以就會有一個名為greet的變量,在<#macro greet>和</#macro>之間的內容(稱為宏定義體)當使用它作為指令時將會被執行。你可以在FTL標記中通過@代替#來使用自定義指令。使用變量名作為指令名。而且,自定義指令的結束標記也是需要的,如:<@greet></@greet>
因為<anything>,/anything>和<anything/>是相同的,你也可以使用:<@greet/>
宏能做的事情還有很多,因為在<#macro...>和</#macro>之間的東西是模板片段,也就是說它可以包含插值(${..})和FTL標簽(如:<#if...>...</#if>)。
注意:程序員通常將使用<@...>,這稱為宏調用。
? ?
參數
在macro指令中,宏名稱的后面位置是用來定義變量的。如例:?
- <#macro?greet?person>??
- ????<font?size="+2">Hello?${person}!</font>??
- </#macro>??
那么就可以這樣來使用這個宏:
- <@greet?person="Fred"/>??
使用預定義指令時,參數的值(=號后邊的值)可以是FTL表達式。這樣,不像HTML,"Fred"的引號就可以不用要了。<@greet person=Fred/>也意味著使用變量的值Fred作為person參數,而不是字符串"Fred"。當然參數值并不一定是字符串類型,也可以是數字,布爾值,哈希表,序列等...也可以在=號左邊使用復雜表達式(比如:someParam=(price+50)*1.25)
自定義指令可以有多個參數,如: ?
- <#macro?greet?person?color>??
- ????<font?size="+2"?color="${color}">Hello?${persion}!</font>??
- </#macro>??
那么,這個宏就可以這樣來使用:
- <@greet?person="Fred"?color="black"/>??
同時也必須給出在宏中定義所有參數的值。如果你嘗試<@greet person="Fred"/>時也會發生錯誤,因為忘記指定color的值了。?
根據FTL表達式規則,明白下面這一點是至關重要的,someParam=foo和someParam="${foo}"是不同的。第一種情況,是把變量foo的值作為參數的值來使用。第二種情況則是使用插值形式的字符串,那么參數值就是字符串了,這個時候,foo的值呈現為文本,而不管foo是什么類型的。
宏參數的另外一個重要的方面是它們是局部變量。
? ?
嵌套內容
自定義指令可以嵌套內容,和預定義指令相似。如:?
- <#macro?border>??
- ????<table?border=4?cellspacing=0?cellpadding=4><tr><td>??
- ????????<#nested>??
- ????</td></tr></table>??
- </#macro>??
注:<#nested>指令執行位于開始和結束標記指令之間的模板代碼段。如果這樣寫:
- <@border>The?bordered?text</@border>??
那么就會輸出:
- <table?border=4?cellspacing=0?cellpadding=4><tr><td>??
- ????The?bordered?text??
- </td></tr></table>??
如果不使用nested指令,那么嵌套的內容就不會被執行,前面的例子如果這樣寫:
- <@greet?person="Joe">??
- ????Anything.??
- </@greet>??
FreeMarker不會把它視為錯誤,只是打印:
- <font?size="+2">Hello?Joe!</font>??
嵌套的內容被忽略了,因為greet宏沒有使用nested指令。
? ?
宏和循環變量
像list這樣的預定義指令可以使用循環變量,如例:
- <#macro?do_thrice>??
- ????<#nested?1>??
- ????<#nested?2>??
- ????<#nested?3>??
- </#macro>??
用戶自定義指令,使用";"代替"as"
- <@do_thrice?;?x>??
- ????${x}?Anything.??
- </@do_thrice>??
將會輸出:
1 Anything.
2 Anything.
3 Anything.
nested指令(當然參數可以是任意的表達式)的參數,循環變量的名稱是在自定義指令的開始標記(<@...>)的參數后面通過分號確定的。