freemarker 宏中可变参数的最小参数
Minimum arguments for variable parameters in freemarker macros
当宏中有可变参数时,例如
<#macro m a b c...>
调用宏时是否必须至少传递 3 个或 2 个参数?这里的参数c
是否必须至少有1个值?另外有什么方法可以默认指定一个参数为null吗?
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
其中:
- name:宏变量名。这不是一个表达。它遵循
与顶级变量引用相同的语法,如 myMacro 或
我的宏。但是,它也可以写成字符串字面量,即
如果宏名称包含不能被
在标识符中指定,例如 <#macro "foo~bar">.... 注意
这个字符串文字不会扩展插值(如
"${foo}").
- param1, param2, ...etc.: 存放的局部变量名
参数值(不是表达式),可选择后跟 = 和
默认值(这是一个表达式)。默认值甚至可以是
另一个参数,例如 <#macro section title label=title>。
参数名称使用与顶级变量相同的语法
引用,因此适用相同的功能和限制。
- paramN,最后一个参数可以选择有 3 个尾随点 (...),
这表明宏采用可变数量的参数
并且与任何其他参数都不匹配的参数将是
收集在最后一个参数中(也称为 catch-all
范围)。当使用命名参数调用宏时,paramN
将是一个包含所有未声明的 key/value 对的散列
传递给宏。当使用位置调用宏时
参数,paramN 将是额外参数的序列
值。 (在宏内部,要找出是哪种情况,您可以
使用 myCatchAllParam?is_sequence.)
因此如您所见,宏对取 N 个参数没有任何限制。
此结构创建一个宏变量(在当前命名空间中,如果您知道命名空间功能)。如果您不熟悉宏并且 user-defined directives 您应该阅读有关用户定义指令的教程。
宏变量存储了一个模板片段(称为宏定义体),可用作用户自定义指令。该变量还将允许的参数名称存储到用户定义的指令中。 使用变量 as 指令时,必须为所有这些参数赋值,具有默认值的参数除外。当且仅当您在调用宏时没有为参数赋值时,才会使用默认值。
变量将在模板的开头创建;宏指令在模板中的位置并不重要。
示例:带有参数的宏:
<#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
但是,关于你问题的最后一部分,有一个 explanation:
空引用是 FreeMarker 中的设计错误。出于您提到的原因,定义自定义空值(它是一个字符串)不是一个好主意。应改用以下结构:
- 宏和函数参数可以有默认值,所以
来电者可以省略它们
- 要检查变量是否为空,您应该使用 ??运算符:<#if
(名字??)>
- 当您使用可以为空的变量时,您应该使用!
指定默认值的运算符:name!"No name"
- 要检查序列(或字符串)是否为空,请使用 ?has_content
内置:<#if(名称?has_content)>
您可以在宏中指定一个空序列作为默认参数值,并简单地测试它是否为空。
当宏中有可变参数时,您不必为最后一个参数传递值。
例如:
<#macro m a b c...>
a = ${a!}
b = ${b!}
<#list c?keys as attr>
${attr} = ${c[attr]}
</#list>
</#macro>
<@m a='A' b='B' />
<@m a='A' b='B' c='C' d='D'/>
将输出:
a = A
b = B
a = A
b = B
c = C
d = D
当宏中有可变参数时,例如
<#macro m a b c...>
调用宏时是否必须至少传递 3 个或 2 个参数?这里的参数c
是否必须至少有1个值?另外有什么方法可以默认指定一个参数为null吗?
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
其中:
- name:宏变量名。这不是一个表达。它遵循 与顶级变量引用相同的语法,如 myMacro 或 我的宏。但是,它也可以写成字符串字面量,即 如果宏名称包含不能被 在标识符中指定,例如 <#macro "foo~bar">.... 注意 这个字符串文字不会扩展插值(如 "${foo}").
- param1, param2, ...etc.: 存放的局部变量名 参数值(不是表达式),可选择后跟 = 和 默认值(这是一个表达式)。默认值甚至可以是 另一个参数,例如 <#macro section title label=title>。 参数名称使用与顶级变量相同的语法 引用,因此适用相同的功能和限制。
- paramN,最后一个参数可以选择有 3 个尾随点 (...), 这表明宏采用可变数量的参数 并且与任何其他参数都不匹配的参数将是 收集在最后一个参数中(也称为 catch-all 范围)。当使用命名参数调用宏时,paramN 将是一个包含所有未声明的 key/value 对的散列 传递给宏。当使用位置调用宏时 参数,paramN 将是额外参数的序列 值。 (在宏内部,要找出是哪种情况,您可以 使用 myCatchAllParam?is_sequence.)
因此如您所见,宏对取 N 个参数没有任何限制。
此结构创建一个宏变量(在当前命名空间中,如果您知道命名空间功能)。如果您不熟悉宏并且 user-defined directives 您应该阅读有关用户定义指令的教程。
宏变量存储了一个模板片段(称为宏定义体),可用作用户自定义指令。该变量还将允许的参数名称存储到用户定义的指令中。 使用变量 as 指令时,必须为所有这些参数赋值,具有默认值的参数除外。当且仅当您在调用宏时没有为参数赋值时,才会使用默认值。
变量将在模板的开头创建;宏指令在模板中的位置并不重要。
示例:带有参数的宏:
<#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
但是,关于你问题的最后一部分,有一个 explanation:
空引用是 FreeMarker 中的设计错误。出于您提到的原因,定义自定义空值(它是一个字符串)不是一个好主意。应改用以下结构:
- 宏和函数参数可以有默认值,所以 来电者可以省略它们
- 要检查变量是否为空,您应该使用 ??运算符:<#if (名字??)>
- 当您使用可以为空的变量时,您应该使用! 指定默认值的运算符:name!"No name"
- 要检查序列(或字符串)是否为空,请使用 ?has_content 内置:<#if(名称?has_content)>
您可以在宏中指定一个空序列作为默认参数值,并简单地测试它是否为空。
当宏中有可变参数时,您不必为最后一个参数传递值。
例如:
<#macro m a b c...>
a = ${a!}
b = ${b!}
<#list c?keys as attr>
${attr} = ${c[attr]}
</#list>
</#macro>
<@m a='A' b='B' />
<@m a='A' b='B' c='C' d='D'/>
将输出:
a = A
b = B
a = A
b = B
c = C
d = D