使用 FreeMarker 内置函数在多行上分配变量

the*_*ker 2 freemarker

我正在尝试使用 FreeMarker 中的内置功能,但在某些情况下遇到问题。

为什么这有效

<#assign foo="bar" />
${foo?trim}
Run Code Online (Sandbox Code Playgroud)

但不是那个

<#assign foo>
    bar
</#assign>
${foo?trim}
Run Code Online (Sandbox Code Playgroud)

我收到这个异常:

FreeMarker template error:
For "?trim" left-hand operand: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to a markup_output (wrapper: f.c.TemplateXHTMLOutputModel):
==> foo  [in template "template.ftl" at line 23, column 7]

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${foo?trim}  [in template "faq.ftl" at line 23, column 5]
----

Java stack trace (for programmers):
----
freemarker.core.NonStringException: [... Exception message was already printed; see it above ...]
    at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:494)
    at freemarker.core.EvalUtil.coerceModelToStringOrUnsupportedMarkup(EvalUtil.java:407)
    at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:107)
    at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
    at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
    at freemarker.core.Expression.eval(Expression.java:81)
    at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:96)
    at freemarker.core.DollarVariable.accept(DollarVariable.java:59)
    at freemarker.core.Environment.visit(Environment.java:362)
    at freemarker.core.Environment.visitAndTransform(Environment.java:460)
    at freemarker.core.BlockAssignment.accept(BlockAssignment.java:55)
    at freemarker.core.Environment.visit(Environment.java:326)
    at freemarker.core.Environment.visit(Environment.java:332)
    at freemarker.core.Environment.process(Environment.java:305)
    at freemarker.template.Template.process(Template.java:384)
    ...
Run Code Online (Sandbox Code Playgroud)

我需要第二种形式,因为bar可能有多行长。
我怎样才能做到这一点?

dde*_*any 5

捕获赋值不适用于创建多行字符串值。这可以通过 来实现<#assign foo="line 1\nline 2">,或者您可以只使用真正的换行符而不是\n(与 Java 不同,FreeMarker 允许这样做):

<#assign foo="
  bar
  baaz
">
${foo?trim}
Run Code Online (Sandbox Code Playgroud)

捕获是为了捕获输出片段,以便可以传递并最终打印。您已捕获标记,因为您的output_format(XHTML ),您已经捕获了标记,如果它碰巧只包含字符数据也没关系,它不再是纯文本,因此字符串操作(不知道捕获的标记的规则,因此可能会损坏它)被禁止。

如果您确实需要这样做,您可以强制捕获的标记串起来,这样您就可以修剪它:${foo?markup_string?trim}。但要知道,如果您捕获了任何标签或实体引用,就会发生不好的事情,除非您也应用?no_esc到修剪后的结果。