如果值为空,Freemarker 不会输入 if/else

问题描述 投票:0回答:4
<#if myVar = "test">
  A
<#else>
  B
<#/if>

如果

myVar
为空/未定义,则 A 和 B 都不会输出。通过在变量后面添加
!
可以解决此问题:

<#if myVar! = "test">
  A
<#else>
  B
<#/if>

这是故意的吗?因为如果是这样,那就非常令人困惑,我无法想象任何用户会期望它以这种方式运行。这表明

null = "test"
在某种程度上既不正确也不错误。很明显,
null = "test"
应该始终被认为是错误的——我错过了什么?

注意:我们已将 Freemarker 配置为用空字符串替换未知变量:

config.setTemplateExceptionHandler((ex, environment, out) ->
{
    if (ex instanceof InvalidReferenceException)
    {
        try
        {
            out.write("");
        }
        catch (IOException e)
        {
            throw new TemplateException("Error while handling template exception.", e, environment);
        }
    }
    else
    {
        throw ex;
    }
});

所以这(至少我认为)最终会是:

<#if "" = "test">
  A
<#else>
  B
<#/if>

在这种情况下,我希望肯定会输入

else
- 但事实并非如此。


给出这个例子:

<#assign myVar = null/>

<#if myVar == "test">
  A
<#else>
  B
</#if>

这会引发以下错误:

以下内容已评估为空或缺失: ==> 空

myVar
已被评估为 null 缺失——这似乎是我困惑的根源;我猜 Freemarker 不区分缺失值和现有但为空的值?

freemarker
4个回答
1
投票

是否是

#if
/
#else
或任何其他指令调用都无关紧要,因为当发生错误时(任何类型的
TemplateException
,而不仅仅是“缺失值”),整个 statement 都会被跳过。不是变量解析,甚至不是整个表达式,而是整个语句。手册和 Javadoc 也是这么说的,请参阅:https://freemarker.apache.org/docs/pgui_config_errorhandling.html。因此,
templateExceptionHandler
设置并不是为缺失值提供默认值。它用于处理真正错误的情况。就像,有人犯了一个错误,有些东西无法运行。

至于为什么不继续使用

#else
。当评估条件时发生错误时,模板引擎无法判断如果开发人员(或任何人)没有犯错误,将会采用哪个分支。选择
if
/
else
的任何一个分支都是一场赌博。 (这甚至不是一场 50-50 的赌博,因为考虑到输出的现实世界含义,正分支往往是正确的分支,但是,如果有的话,人们希望模板引擎赌在
else
分支上。) ,希望您至少会打印一些错误指示符,它不会选择任何一个分支。但这确实是自动的,因为整个
#if
/
#elseif
/
#else
事情就是一个大声明。


0
投票
<#assign myVar = "test"/>

<#if myVar?? && myVar == "test">
  A
<#else>
  B
</#if>

0
投票

是的,这是有意的。当变量未定义或为 null 时,freemarker 将引发错误。

常见问题解答中对此进行了解释:为什么 FreeMarker 对 null 和缺失变量如此挑剔,以及如何处理它们?

这是框架最初作者的设计选择。如果您对此选择不满意,可以使用 默认值运算符(使用

myVar!
而不是
myVar
),或使用其他模板框架。

您添加的自定义异常处理程序不会用空字符串替换表达式,而是替换完整的 if/else 表达式。


0
投票

这样使用

<#if condition 1>
-- do here your work for condition 1
<#else>
<#if condition 2>
-- do here your work for condition 2
    <#else>
-- do here your work for else
    </#if>
</#if>
© www.soinside.com 2019 - 2024. All rights reserved.