在多行上使用带有分配变量的 FreeMarker 内置函数
Using FreeMarker built-ins with assigned variables over multiple lines
我正在尝试使用 FreeMarker 中的内置功能,但我在某些情况下遇到了问题。
为什么这样做有效
<#assign foo="bar" />
${foo?trim}
但不是那样
<#assign foo>
bar
</#assign>
${foo?trim}
?
我遇到了这个异常:
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)
...
我需要第二种形式,因为 bar
可以是多行。
我怎样才能做到这一点?
捕获赋值不适用于创建多行字符串值。这可以用 <#assign foo="line 1\nline 2">
来实现,或者你可以只使用一个真正的换行符而不是 \n
(不像 Java,FreeMarker 允许这样做):
<#assign foo="
bar
baaz
">
${foo?trim}
捕获是为了捕获输出片段,以便它可以传递并最终打印出来。由于 output_format
(XHTML
),您已经捕获了标记,如果它恰好只包含字符数据,它不再是纯文本,那么字符串操作(不是了解捕获标记的规则并因此可能破坏它)被禁止使用它。
如果您真的需要这样做,您可以将捕获的标记强制为字符串,这样您就可以 trim 它:${foo?markup_string?trim}
。但是要知道,如果您捕获了任何标签或实体引用,就会发生不好的事情,除非您还在 trimmed 结果上应用 ?no_esc
。
我正在尝试使用 FreeMarker 中的内置功能,但我在某些情况下遇到了问题。
为什么这样做有效
<#assign foo="bar" />
${foo?trim}
但不是那样
<#assign foo>
bar
</#assign>
${foo?trim}
?
我遇到了这个异常:
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)
...
我需要第二种形式,因为 bar
可以是多行。
我怎样才能做到这一点?
捕获赋值不适用于创建多行字符串值。这可以用 <#assign foo="line 1\nline 2">
来实现,或者你可以只使用一个真正的换行符而不是 \n
(不像 Java,FreeMarker 允许这样做):
<#assign foo="
bar
baaz
">
${foo?trim}
捕获是为了捕获输出片段,以便它可以传递并最终打印出来。由于 output_format
(XHTML
),您已经捕获了标记,如果它恰好只包含字符数据,它不再是纯文本,那么字符串操作(不是了解捕获标记的规则并因此可能破坏它)被禁止使用它。
如果您真的需要这样做,您可以将捕获的标记强制为字符串,这样您就可以 trim 它:${foo?markup_string?trim}
。但是要知道,如果您捕获了任何标签或实体引用,就会发生不好的事情,除非您还在 trimmed 结果上应用 ?no_esc
。