逃逸,不逃逸(已弃用)

Page Contents

Synopsis

<#escape identifier as expression>
  ...
  <#noescape>...</#noescape>
  ...
</#escape>

骆驼的案例名称变体:noEscape

Description

Note:

自 2.3.24 起,这些指令已被output-format-based auto-escaping弃用*。此外,在使用自动转义的地方(实际上具有转义的输出格式),您不允许使用escape指令(无论如何您都将从解析错误消息中找到)。

当使用转义指令围绕模板的一部分时,在块内发生的插值(${...})将自动与转义表达式组合。这是一种避免重复编写类似表达式的便捷方法。它不会影响字符串 Literals 中的插值(如<#assign x = "Hello ${user}!">)。而且,它不影响数值插值(#{...})。

Example:

<#escape x as x?html>
  First name: ${firstName}
  Last name: ${lastName}
  Maiden name: ${maidenName}
</#escape>

实际上等效于:

First name: ${firstName?html}
  Last name: ${lastName?html}
  Maiden name: ${maidenName?html}

注意,在指令中使用什么标识符无关紧要-它只是用作转义表达式的形式参数。

当您调用宏或include指令时,重要的是要了解转义仅对模板文本*中<#escape ...></#escape>之间发生的插值有效。也就是说,即使从escape -d 部分内部调用了该部分,也不会转义文本中<#escape ...>之前或</#escape>之后的任何内容。

<#assign x = "<test>">
<#macro m1>
  m1: ${x}
</#macro>
<#escape x as x?html>
  <#macro m2>m2: ${x}</#macro>
  ${x}
  <@m1/>
</#escape>
${x}
<@m2/>

输出将是:

&lt;test&gt;
  m1: <test>
<test>
m2: &lt;test&gt;

从技术上讲,escape指令的效果是在模板解析时而不是在模板处理时应用的。这意味着,如果您从转义块中调用宏或包含另一个模板,则不会影响宏/包含的模板中的插值,因为宏调用和包含的模板是在模板处理时评估的。另一方面,如果用转义块将一个或多个宏声明(在模板解析时评估,而不是宏调用)包围起来,则这些宏中的插值将与转义表达式组合。

有时需要暂时关闭转义块中用于一两次插值的转义。您可以通过关闭并稍后重新打开转义块来实现此目的,但是随后您必须编写两次转义表达式。您可以改用 noescape 指令:

<#escape x as x?html>
  From: ${mailMessage.From}
  Subject: ${mailMessage.Subject}
  <#noescape>Message: ${mailMessage.htmlFormattedBody}</#noescape>
  ...
</#escape>

等效于:

From: ${mailMessage.From?html}
  Subject: ${mailMessage.Subject?html}
  Message: ${mailMessage.htmlFormattedBody}
  ...

转义符可以嵌套(尽管仅在极少数情况下会这样做)。因此,您可以编写类似以下代码的代码(示例可能有些延伸,因为您可能会将项目代码放置在序列中,并使用list对其进行迭代,但是我们现在这样做只是为了说明要点):

<#escape x as x?html>
  Customer Name: ${customerName}
  Items to ship:
  <#escape x as itemCodeToNameMap[x]>
    ${itemCode1}
    ${itemCode2}
    ${itemCode3}
    ${itemCode4}
  </#escape>
</#escape>

实际上等效于:

Customer Name: ${customerName?html}
  Items to ship:
    ${itemCodeToNameMap[itemCode1]?html}
    ${itemCodeToNameMap[itemCode2]?html}
    ${itemCodeToNameMap[itemCode3]?html}
    ${itemCodeToNameMap[itemCode4]?html}

在嵌套转义块中使用 noescape 指令时,它仅撤消单个转义级别。因此,要完全关闭两级深度转义块中的转义,还需要使用两个嵌套的 noescape 指令。

上一章 首页 下一章