在 Freemarker 模板中设置嵌套 属性

Set nested property in Freemarker template

我在 Alfresco 工作,我想创建自己的自定义组件(用于表单)以扩展现有组件。就我而言 "number.ftl".

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

默认-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 中的点 (.):

Caused by: freemarker.core.ParseException: Parsing error in template "org/alfresco/components/form/controls/year.ftl" in line 3, column 23: Encountered ".", but was expecting one of: "=" "in" ">"

如何设置变量?

更新

我已经按照 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 template error: For "#assign" namespace: Expected a namespace, but this evaluated to an extended_hash+string (org.alfresco.web.scripts.forms.FormUIGet$Field wrapped into f.e.b.StringModel): ==> field [in template "org/alfresco/components/form/controls/year.ftl" at line 3, column 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" />

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

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

这样解释:

If you know what namespaces are: assign directive creates variables in namespaces. Normally it creates the variable in the current namespace (i.e. in the namespace associated with the template where the tag is). However, if you use in namespacehash then you can create/replace a variable of another namespace than the current namespace. For example, here you create/replace variable bgColor of the namespace used for /mylib.ftl:

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

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

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