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