On this page
宏,嵌套,返回
Page Contents
Synopsis
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
Where:
name
:宏变量的名称。这不是表达。它遵循与像顶级变量引用相同的语法,例如myMacro
或my\-macro
。但是,它也可以写为字符串 Literals,如果宏名称包含无法在标识符中指定的字符,例如<#macro "foo~bar">...
,则很有用。请注意,此字符串 Literals 不会扩展插值(如"${foo}"
)。param1
,param2
,...等:local variables的名称存储参数值(不是表达式),可以选择后面跟着=
和默认值(即表达式)。默认值甚至可以是另一个参数,例如<#macro section title label=title>
。参数名称使用与像顶级变量引用相同的语法,因此具有相同的功能和限制。paramN
,最后一个参数可以选择包含 3 个尾随点(...
),这表示该宏采用可变数量的参数,并且不匹配任何其他参数的参数将被收集到该最后一个参数中(也称为 catch-所有参数)。当使用命名参数调用宏时,paramN
将是一个散列,其中包含所有传递给宏的未声明键/值对。当使用位置参数调用宏时,paramN
将是额外参数值的序列。 (在宏中,可以使用myCatchAllParam?is_sequence
来确定是哪种情况)。loopvar1
,loopvar2
,...等:可选。nested
指令要为嵌套内容创建的loop variables值。这些是表达式。
return
和nested
伪指令是可选的,并且可以在<#macro ...>
和</#macro>
之间的任何位置和任何时间使用。
没有默认值的参数必须在带有默认值(paramName=defaultValue
)的参数之前。
Description
创建一个宏变量(如果知道名称空间功能,则在当前名称空间中)。如果您不熟悉宏和用户定义的指令,则应阅读关于用户定义指令的教程。
宏变量存储可以用作user-defined directive的模板片段(称为宏定义主体)。该变量还将允许的参数名称存储到用户定义的指令中。使用变量作为指令时,必须为所有这些参数提供值,具有默认值的参数除外。当且仅当调用宏时不给参数值时,才使用默认值。
该变量将在模板的开头创建;它与模板中放置macro
指令的位置无关。因此,这将起作用:
<#-- call the macro; the macro variable is already created: -->
<@test/>
...
<#-- create the macro variable: -->
<#macro test>
Test text
</#macro>
但是,如果宏定义是通过include
指令插入的,则在 FreeMarker 执行include
指令之前它们将不可用。
示例:不带参数的宏:
<#macro test>
Test text
</#macro>
<#-- call the macro: -->
<@test/>
Output:
Test text
示例:带有参数的宏:
<#macro test foo bar baaz>
Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<#-- call the macro: -->
<@test foo="a" bar="b" baaz=5*5-2/>
Output:
Test text, and the params: a, b, 23
示例:具有参数和默认参数值的宏:
<#macro test foo bar="Bar" baaz=-1>
Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<@test foo="a" bar="b" baaz=5*5-2/>
<@test foo="a" bar="b"/>
<@test foo="a" baaz=5*5-2/>
<@test foo="a"/>
Output:
Test text, and the params: a, b, 23
Test text, and the params: a, b, -1
Test text, and the params: a, Bar, 23
Test text, and the params: a, Bar, -1
示例:一个更复杂的宏。
<#macro list title items>
<p>${title?cap_first}:
<ul>
<#list items as x>
<li>${x?cap_first}
</#list>
</ul>
</#macro>
<@list items=["mouse", "elephant", "python"] title="Animals"/>
Output:
<p>Animals:
<ul>
<li>Mouse
<li>Elephant
<li>Python
</ul>
示例:支持可变数量的命名参数的宏:
<#macro img src extra...>
<img src="/myapp${src?ensure_starts_with('/')}"
<#list extra as attrName, attrVal>
${attrName}="${attrVal}"
</#list>
>
</#macro>
<@img src="/images/test.png" width=100 height=50 alt="Test"/>
Output:
<img src="/context/images/test.png"
alt="Test"
height="50"
width="100"
>
示例:一个宏,它支持可变数量的位置参数,无论它使用命名还是位置参数传递:
<#macro m a b ext...>
a = ${a}
b = ${b}
<#if ext?is_sequence>
<#list ext as e>
${e?index} = ${e}
</#list>
<#else>
<#list ext as k, v>
${k} = ${v}
</#list>
</#if>
</#macro>
<@m 1 2 3 4 5 />
<@m a=1 b=2 c=3 d=4 e=5 data\-foo=6 myns\:bar=7 />
Output:
a = 1
b = 2
0 = 3
1 = 4
2 = 5
a = 1
b = 2
c = 3
d = 4
e = 5
data-foo=6
myns:bar=7
Warning!
在 FreeMarker 2.3.30 之前,命名的包罗万象的参数是无序的,也就是说,您不知道将枚举它们的 Sequences。仅从 2.3.30 开始,它们以与传递时相同的 Sequences 返回。
nested
nested
指令在用户定义的指令的开始标记和结束标记之间执行模板片段。嵌套部分可以包含模板中有效的任何内容。插值,指令等它是在调用宏的上下文中执行的,而不是在宏定义主体的上下文中执行的。因此,例如,您在嵌套部分中看不到宏的局部变量。如果您不调用nested
指令,则用户定义的指令的开始标记和结束标记之间的部分将被忽略。
Example:
<#macro do_twice>
1. <#nested>
2. <#nested>
</#macro>
<@do_twice>something</@do_twice>
1. something
2. something
nested 指令可以为嵌套内容创建循环变量。例如:
<#macro do_thrice>
<#nested 1>
<#nested 2>
<#nested 3>
</#macro>
<@do_thrice ; x>
${x} Anything.
</@do_thrice>
1 Anything.
2 Anything.
3 Anything.
一个更复杂的示例:
<#macro repeat count>
<#list 1..count as x>
<#nested x, x/2, x==count>
</#list>
</#macro>
<@repeat count=4 ; c, halfc, last>
${c}. ${halfc}<#if last> Last!</#if>
</@repeat>
1. 0.5
2. 1
3. 1.5
4. 2 Last!
return
使用return
指令,可以将宏或函数定义主体保留在任何位置。例:
<#macro test>
Test text
<#return>
Will not be printed.
</#macro>
<@test/>
Test text