在 Freemarker 模板中设置嵌套属性

Posted

技术标签:

【中文标题】在 Freemarker 模板中设置嵌套属性【英文标题】:Set nested property in Freemarker template 【发布时间】:2015-05-19 19:30:56 【问题描述】:

我在 Alfresco 工作,我想创建自己的自定义组件(用于表单)来扩展现有组件。在我的例子中是“number.ftl”。

我想提供设置默认值的功能,这样如果field.value 为空,则将使用默认值

default-number.flt

<#if field.control.params.defaultValue?? && !field.value?has_content>
    <#assign field.value=field.control.params.defaultValue>
</#if>
<#include "/org/alfresco/components/form/controls/number.ftl" />

它抱怨field.value中的点(。):

原因:freemarker.core.ParseException:第 3 行第 23 列模板“org/alfresco/components/form/controls/year.ftl”中的解析错误: 遇到“。”,但期待以下之一: “=” “在” ">"

如何设置变量?

更新

我已经按照 abarisone 的建议进行了尝试(但在导入“number.ftl”后我无法设置变量,否则将使用旧值):

<#if field.control.params.curretYearDefaultValue?? && !field.value?has_content>
    <#assign value in field>
        $.now?string("yy")
    </#assign>
</#if>
<#include "/org/alfresco/components/form/controls/number.ftl" />

但我明白了:

FreeMarker 模板错误:对于“#assign”命名空间:应为命名空间,但这评估为扩展哈希 + 字符串(org.alfresco.web.scripts.forms.FormUIGet$Field 包装到 febStringModel):==> 字段[在模板“org/alfresco/components/form/controls/year.ftl”第 3 行第 27 列]

UPDATE2(已解决)

正如 ddekany 建议的那样,一个可行的解决方案

<#if field.control.params.useCurretYearAsDefaultValue?? && field.control.params.useCurretYearAsDefaultValue = "true" && !field.value?has_content>
    $field.setValue(.now?string("yyyy"))!
</#if>
<#include "/org/alfresco/components/form/controls/number.ftl" />

【问题讨论】:

【参考方案1】:

FreeMarker 模板不支持数据模型修改。他们只打算阅读 Java 代码已经准备好的东西。您只能设置***变量,因为它们不是数据模型的一部分(它们位于***数据模型变量之前的范围内)。所以 FreeMarker 甚至没有修改子变量的语法。但是,可能存在一个后门来实现您想要的。根据配置设置和 field 在 Java 级别上的设置,$field.setValue(...) 可能会起作用。请注意,这样做是一件很困难的事情。从模板操作表单内容,这很糟糕。您至少应该调用一些 Java 辅助方法。

【讨论】:

【参考方案2】:

如果您查看Freemarker assign reference,您会发现,当您使用assign 时,您通常会写&lt;#assign name=value&gt;,其中name 是变量的名称。它不是表达。 事实上,编译器抱怨它期待“=”或“in”的事实。 如果您进一步研究,后者是有道理的:

<#assign name in namespacehash>
  capture this
</#assign>

这样解释:

如果你知道命名空间是什么:assign 指令在命名空间中创建变量。通常它在当前命名空间中创建变量(即在与标签所在的模板关联的命名空间中)。但是,如果您在 namespacehash 中使用,那么您可以创建/替换除当前命名空间之外的另一个命名空间的变量。例如,在这里您创建/替换用于 /mylib.ftl 的命名空间的变量 bgColor:

<#import "/mylib.ftl" as my>
<#assign bgColor="red" in my>  

所以我建议你先导入number.ftl文件,然后搜索你要设置的变量。

【讨论】:

谢谢,但“字段”不是命名空间,我得到“预期命名空间”。请看我的帖子更新 事实上,在我的示例中,命名空间是“my”。必须在使用之前插入包含并作为 namespacehash 引用 好的,但这不是我的情况:“field.value”在 number.ftl 中使用,我必须先设置它。将文件(不是库)导入命名空间将毫无用处,因为它没有定义任何变量,而是使用了一些已经定义的变量(我想谁将包含我自己的文件)

以上是关于在 Freemarker 模板中设置嵌套属性的主要内容,如果未能解决你的问题,请参考以下文章

在 Struts2 中设置响应的内容类型

如何使用 aws cloudformation 模板在 aws cognito 用户池中设置所需属性?

使用 USCavalry 转换器将 Velocity 模板转换为 FreeMarker

Freemarker的使用方法

使用 freemarker(或任何其他模板引擎)处理多个嵌套模板

Java 使用 freemarker 模板引擎的相关疑问 ,求大神走过路过不要错过