User-defined directive (<@...>)

概要

<@user_def_dir_exp param1=val1 param2=val2 ... paramN=valN/>
(注意 XML 风格, /> 之前)  
或如果需要循环变量 (更多细节...)
<@user_def_dir_exp param1=val1 param2=val2 ... paramN=valN ; lv1, lv2, ..., lvN/>

或和上面两个相同但是使用结束标签 (更多细节...):

<@user_def_dir_exp ...>
  ...
</@user_def_dir_exp><@user_def_dir_exp ...>
  ...
</@>

或和上面的相同但是使用位置参数传递 (更多细节...):

<@user val1, val2, ..., valN/>
等...

这里:

  • user_def_dir_exp: 表达式算作是自定义指令(比如宏),将会被调用。
  • param1param2等...: 参数的名称,它们 不是 表达式。
  • val1val2等...: 参数的值,它们 表达式。
  • lv1lv2等...: 循环变量 的名称, 它们 不是 表达式。

参数的数量可以是0(也就是没有参数)。

参数的顺序并不重要(除非你使用了位置参数传递)。 参数名称必须唯一。在参数名中小写和大写的字母被认为是不同的字母 (也就是 Colorcolor 是不同的)。

描述

这将调用用户自定义指令,比如宏。参数的含义, 支持和需要的参数的设置依赖于具体的自定义指令。

你可以阅读 自定义指令

示例1:调用存储在变量 html_escape 中的指令:

<@html_escape>
  a < b
  Romeo & Juliet
</@html_escape>

将会输出:

  a &lt; b
  Romeo &amp; Juliet

示例2:调用有参数的宏:

<@list items=["mouse", "elephant", "python"] title="Animals"/>
...
<#macro list title items>
  <p>${title?cap_first}:
  <ul>
    <#list items as x>
      <li>${x?cap_first}
    </#list>
  </ul>
</#macro>

将会输出:

  <p>Animals:
  <ul>
      <li>Mouse
      <li>Elephant
      <li>Python
  </ul>
  
...

结束标签

你可以在 结束标签 中忽略 user_def_dir_exp。 也就是说,你可以写 </@> 来替代 </@anything>。 这个规则当表达式 user_def_dir_exp 太复杂时非常有用,因为你不需要在结束标签中重复表达式。 此外,如果表达式包含比简单变量名和点还多的表达式,你就不能再重复它们了。比如, <@a_hash[a_method()]>...</@a_hash[a_method()]> 就是错的,你必须写为 <@a_hash[a_method()]>...</@>。 但是 <@a_hash.foo>...</@a_hash.foo> 是可以的。

循环变量

一些自定义指令创建循环变量(和 list 指令相似)。 正如预定义指令(如 list)一样,当你调用这个指令 (如 <#list foos as foo>...</#list>中的 foo)时循环变量的 名称 就给定了, 而变量的 是由指令本身设置的。 在自定义指令的情形下,语法是循环变量的名称在分号之后给定。比如:

<@myRepeatMacro count=4 ; x, last>
  ${x}. Something... <#if last> This was the last!</#if>
</@myRepeatMacro>

请注意,由自定义指令创建的循环变量数量和分号之后指定的循环变量数量需要不匹配。 也就是说,如果你对重复是否是最后一个不感兴趣,你可以简单来写:

<@myRepeatMacro count=4 ; x>
  ${x}. Something...
</@myRepeatMacro>

或者你可以:

<@myRepeatMacro count=4>
  Something...
</@myRepeatMacro>

此外,如果你在分号之后指定更多循环变量而不是自定义指令创建的, 也不会引起错误,只是最后的循环变量不能被创建 (也就是在嵌套内容中那些将是未定义的)。尝试使用未定义的循环变量, 就会引起错误(除非你使用如 ?default 这样的内建函数), 因为你尝试访问了一个不存在的变量。

参考 自定义指令 来获取更多内容。

位置参数传递

位置参数传递(如<@heading "Preface", 1/>) 是正常命名参数传递(如<@heading title="Preface" level=1/>) 的速记形式,这里忽略了参数的名称。如果自定义指令只有一个参数, 或者对于经常使用的自定义指令它参数的顺序很好记忆,速记形式应该被应用。 为了应用这种形式,你不得不了解声明的命名参数的顺序(如果指令只有一个参数这是很琐碎的)。 也就是,如果 heading 被创建为 <#macro heading title level>..., 那么 <@heading "Preface", 1/><@heading title="Preface" level=1/> (或 <@heading level=1 title="Preface"/>; 如果你使用参数名称,那顺序就不重要了)是相等的。 要注意位置参数传递现在仅仅支持宏定义。