freemarker宏中变量参数的最小参数

时间:2016-04-20 09:56:46

标签: macros freemarker

在宏中有可变参数时,例如

 <#macro m a b c...>

调用宏时,你必须传递至少3个参数或2个参数吗?这里的参数c是否必须至少有1个值?还有什么方法可以默认将参数指定为null吗?

2 个答案:

答案 0 :(得分:5)

<#macro name param1 param2 ... paramN>
  ...
  <#nested loopvar1, loopvar2, ..., loopvarN>
  ...
  <#return>
  ...
</#macro>

其中:

  • name:宏变量的名称。这不是表达。它遵循 与顶级变量引用相同的语法,如myMacro或 我的宏。但是,它也可以写成字符串文字,即 如果宏名称包含不能的字符,则非常有用 在标识符中指定,例如&lt; #macro“foo~bar”&gt; ....注意 这个字符串文字不会扩展插值(如 “$ {FOO}”)。
  • param1,param2,...等:存储局部变量的名称 参数值(不是表达式),可选地后跟=和 默认值(这是一个表达式)。默认值甚至可以 另一个参数,例如&lt; #macro section title label = title&gt;。 参数名称使用与顶级变量相同的语法 引用,因此适用相同的功能和限制。
  • paramN,最后一个参数可以选择有3个尾随点(...), 表示宏采用可变数量的参数 以及与任何其他参数不匹配的参数 收集在这最后一个参数(也称为catch-all 参数)。使用命名参数paramN调用宏时 将是包含所有未声明的键/值对的哈希 传递到宏。使用位置调用宏时 参数,paramN将是额外参数的序列 值。 (在宏观内部,要找出哪种情况,你可以 使用myCatchAllParam?is_sequence。)

因此,您可以看到宏对N参数没有任何限制。

此结构创建一个宏变量(如果您知道命名空间功能,则在当前命名空间中)。如果您不熟悉宏和user-defined directives,那么您应该阅读有关用户定义指令的教程。

宏变量存储可用作用户定义指令的模板片段(称为宏定义主体)。该变量还将允许的参数名称存储到用户定义的指令中。 当您将变量用作指令时,必须为所有这些参数赋值,但具有默认值的参数除外。当且仅当您在调用宏时没有为参数赋值时,才会使用默认值。

变量将在模板的开头创建;它不会将宏指令放在模板中的位置。

示例:带参数的宏:

<#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/>
  

输出:

 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"/>
  

输出:

  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中的错误。由于您提到的原因,定义自定义空值 - 这是一个字符串 - 不是一个好主意。应该使用以下结构:

  • 宏和函数参数可以有一个默认值,所以 来电者可以省略它们
  • 要检查变量是否为null,您应该使用??运算符:&lt; #if (名称?)&GT;
  • 当你使用一个可以为null的变量时,你应该使用! 运算符指定默认值:name!“No name”
  • 要检查序列(或字符串)是否为空,请使用?has_content builtin:&lt; #if(names?has_content)&gt;

您可以在宏中指定一个空序列作为默认参数值,只需测试它是否为空。

答案 1 :(得分:0)

如果宏中有变量参数,则不必为最后一个参数传递值。

例如:

<#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