我正在使用Freemarker构建一个站点并且已经开始大量使用宏.我知道在Freemarker 2.3中,将空值作为参数传递给宏等同于根本不传递参数所以我创建了一个名为"null"的全局变量来模拟我的宏中的空值检查:
<#assign null="NUL" />
Run Code Online (Sandbox Code Playgroud)
现在在我的宏中我可以这样做:
<#maco doSomething param1=null>
<#if param1 != null>
<div>WIN!</div>
</#if>
</#macro>
Run Code Online (Sandbox Code Playgroud)
如果我想传递一个不是标量的参数,问题就来了.例如,将List(在Freemarker中是SimpleSequence)传递给宏并检查我的null关键字会产生错误:
freemarker.template.TemplateException:唯一合法的比较是在两个数字,两个字符串或两个日期之间.左手操作数是freemarker.template.SimpleSequence右手操作数是freemarker.template.SimpleScalar
我看了一下freemarker代码,我可以看到问题(ComparisonExpression.isTrue()):
if(ltm instanceof TemplateNumberModel && rtm instanceof TemplateNumberModel) {
...
}
else if(ltm instanceof TemplateDateModel && rtm instanceof TemplateDateModel) {
...
}
else if(ltm instanceof TemplateScalarModel && rtm instanceof TemplateScalarModel) {
...
}
else if(ltm instanceof TemplateBooleanModel && rtm instanceof TemplateBooleanModel) {
...
}
// Here we handle compatibility issues
else if(env.isClassicCompatible()) {
...
}
else {
throw new TemplateException("The only legal comparisons...", env);
}
Run Code Online (Sandbox Code Playgroud)
所以我能想到的唯一解决方案是将isClassicCompatible设置为true,我认为它会在两个对象上调用toString()并比较结果.但是,文档明确指出应该重写任何依赖旧功能的内容.
我的问题是,是否有一个不依赖于弃用功能的解决方案?
Lau*_*eyn 19
所述null参考是由设计在FreeMarker的错误.由于您提到的原因,定义自定义空值 - 这是一个字符串 - 不是一个好主意.应该使用以下构造:
null,您应该使用??运算符:<#if (name??)>null,您应该使用!运算符指定默认值:name!"No name"?has_content内置函数:<#if (names?has_content)>您可以在宏中将空序列指定为默认参数值,并只测试它是否为空.
这就是我所做的,这似乎适用于大多数场景:
默认值应为空字符串,null检查应为?has_content.
<#macro someMacro optionalParam="" >
<#if (optionalParam?has_content)>
<#-- NOT NULL -->
<#else>
<#-- NULL -->
</#if>
</#macro>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18792 次 |
| 最近记录: |