宏,嵌套,返回

Page Contents

Synopsis

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

Where:

  • name:宏变量的名称。这不是表达。它遵循与像顶级变量引用相同的语法,例如myMacromy\-macro。但是,它也可以写为字符串 Literals,如果宏名称包含无法在标识符中指定的字符,例如<#macro "foo~bar">...,则很有用。请注意,此字符串 Literals 不会扩展插值(如"${foo}")。

  • param1param2,...等:local variables的名称存储参数值(不是表达式),可以选择后面跟着=和默认值(即表达式)。默认值甚至可以是另一个参数,例如<#macro section title label=title>。参数名称使用与像顶级变量引用相同的语法,因此具有相同的功能和限制。

  • paramN,最后一个参数可以选择包含 3 个尾随点(...),这表示该宏采用可变数量的参数,并且不匹配任何其他参数的参数将被收集到该最后一个参数中(也称为 catch-所有参数)。当使用命名参数调用宏时,paramN将是一个散列,其中包含所有传递给宏的未声明键/值对。当使用位置参数调用宏时,paramN将是额外参数值的序列。 (在宏中,可以使用myCatchAllParam?is_sequence来确定是哪种情况)。

  • loopvar1loopvar2,...等:可选。 nested指令要为嵌套内容创建的loop variables值。这些是表达式。

returnnested伪指令是可选的,并且可以在<#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