我正在使用 Freemarker 构建一个网站,并开始大量使用宏。我知道在 Freemarker 2.3 中,将 null 值作为参数传递到宏中相当于根本不传递参数,因此我创建了一个名为“null”的全局变量来模拟宏中的 null 检查:
<#assign null="NUL" />
现在在我的宏中我可以这样做:
<#macro doSomething param1=null>
<#if param1 != null>
<div>WIN!</div>
</#if>
</#macro>
如果我想传递一个不是标量的参数,就会出现问题。例如,将列表(在 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);
}
所以我能想到的唯一解决方案是将 isClassicCompatible 设置为 true,我认为这会在两个对象上调用 toString() 并比较结果。但是,文档特别指出任何依赖于旧功能的内容都应该重写。
我的问题是,是否有一个不依赖已弃用功能的解决方案?
The null
引用是 FreeMarker 中设计的一个错误。由于您提到的原因,定义自定义空值(它是一个字符串)并不是一个好主意。应改用以下结构:
- 宏和函数参数可以有默认值,因此调用者可以省略它们
- 检查变量是否是
null
,你应该使用??
操作员:<#if (name??)>
- 当您使用一个变量时,可以
null
,你应该使用!
运算符指定默认值:name!"No name"
- 要检查序列(或字符串)是否为空,请使用
?has_content
内置:<#if (names?has_content)>
您可以在宏中指定一个空序列作为默认参数值,并简单地测试它是否为空。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)