宏(macro)是自定义指令(directive)的一种方法,使用宏能实现在模版级别自定义指令,另一种自定义指令的方式是再Java级别实现指令。
宏的概念
宏是对一段模版片段的定义,在定义宏后,可通过用户自定义指令的语法<@ macro_name />
引用,宏本身通过<#macro></#macro>
预定义指令定义。
<#macro hello>
Hello!
</#macro>
<@hello/> <#--输出: Hello!-->
在<#macro></#macro>
预定义指令间可以包括任何模版文本和FTL元素。
参数
宏可以在定义时指定接受参数,通过在宏名后跟参数名定义参数。
<#macro hello who>
Hello! ${who}!
</#macro>
<@hello "skyupward"/> <#--输出: Hello skyupward!-->
参数可以定义多个,以及提供默认值,支持位置参数调用和命名参数调用。
<#macro hello who1st who2nd who_always="skyupward">
Hello! ${who1st} ${who2nd} ${who_always}!
</#macro>
<@hello "cool" "hot"/> <#--输出: Hello cool hot skyupward!-->
<@hello who_always="skyupward" who1st="cool" who2nd="hot"/> <#--输出: Hello cool hot skyupward!-->
定义宏的参数时多参数之间可以用空白字符分隔,也可以用“,”,但推荐用空白分隔多个参数的形式,统一定义和赋值,同时赋值使用命名参数的形式。在调用时命名参数调用不支持","作为分隔符,顺序参数调用和命名参数调用不可同时使用,此外在复杂的表达式情形下用空格方式分隔多参数的顺序调用方式可能出现语法解析错误。比如:
<@hello he (2>1)?string('you', 'me') />
无法解析
嵌套引用
宏支持在调用是具有嵌套体,同时通过指令<#nested>
引用。
<#macro hello>
Hello skyupward!
<#nested>
</#macro>
<@hello>say from skyupward self.</@hello>
<#--输出:
Hello skyupward!
say from skyupward self.
-->
嵌套体内部不能引用宏定义的本地变量,包括宏声明的参数。
嵌套传参
指令<#nested>
支持通过语法<#nested params>
传递参数,这些参数可以在嵌套体中使用,通过在调用宏时以<#macro marcro_name [arguments] [; ref_names]>
的方式按声明顺序指定指定引用参数名。
<#macro hello av>
Hello skyupward!
<#nested "1st" >
<#nested "2nd" >
</#macro>
<@hello 1; times>${times} say from skyupward self.</@hello>
<#--输出:
Hello skyupward!
1st say from skyupward self.2nd say from skyupward self.
-->
在传递嵌套体变量和命名嵌套体变量引用时,多参数之间用“,”分隔。在传递变量时,只要freemaker能识别出不同变量的分隔位置,也能采用不使用","分隔的方式传递,比如
<#nested "1"2 3>
不过这不是一种好实践。
当多次引用嵌套体的时候,变量引用就成了所谓的循环变量。