2.3

Page Contents

发布日期:2004 年 6 月 15 日

与 2.2.x 系列相比,FreeMarker 2.3 引入了许多小的新功能和质量改进。最显着的改进是在模板中定义函数(方法)的能力,在字符串 Literals 中插值变量的能力,对可变数量的宏参数的支持以及更智能的默认对象包装器。尽管这些改进都没有很大的变化,但是 2.3.x 系列与 2.2.x 系列没有向后兼容(请参阅下面的列表),因此您可以选择仅将其用于新项目。

可能最“大声推广”的新功能是完全重新设计的 XML 包装器。借助新的 XML 包装器,FreeMarker 定位到一个新的应用程序域,该域类似于 XSLT 的应用程序域:将复杂的 XML 转换为任何文本输出。尽管这个子项目还很年轻,但实际上可以使用。有关更多详细信息,请参见XML 处理指南

非向后兼容的更改!

  • 由于插值(${...}#{...})现在可以在字符串 Literals 中使用,因此保留字符串 Literals 中的字符序列${#{。因此,如果您有类似<#set x = "${foo}">的内容,则必须将其替换为<#set x = r"${foo}">-请注意,诸如\n之类的转义符不适用于原始(r)字符串。

  • strict_syntax设置的默认(初始)值已从false更改为true。当strict_syntaxtrue时,具有<include "foo.ftl">的旧语法的标记将被视为静态文本(因此它们像 HTML 标记一样按原样转到输出),而不是 FTL 标记。此类标签必须重写为<#include "foo.ftl">,因为只有以<#</#<@</@开头的部分才算作 FTL 标签。或者,要恢复识别旧标记语法和新标记语法的旧过渡行为,必须将strict_syntax设置为falsecfg.setStrictSyntaxMode(false)。另外,对于单个模板,您可以通过以<#ftl strict_syntax=false>开头模板来强制执行旧的行为。 (有关为什么严格语法比旧语法read this...更好的更多信息)

  • 几个类从freemarker.template包移到了新的freemarker.core包:

  • “普通”类:ArithmeticEngineConfigurable,* Environment *

    • exception:InvalidReferenceExceptionNonBooleanExceptionNonNumericalExceptionNonStringExceptionParseExceptionStopException

    • 错误:TokenMgrError

freemarker.template软件包拆分的主要原因是,随着我们为第三方工具(例如调试 API)引入 API,“maven”公共类和接口的数量增长过多。

  • freemarker.template.TemplateMethodModel.exec现在返回Object而不是TemplateModel

  • 现在,空格剥离现在比以前更加积极:如果行仅包含 FTL 标签,它将始终删除前导和尾随空格。 (以前,如果标记是<#include ...>或具有空指令语法为<@myMacro/>的用户定义的指令标记(或等效标记<@myMacro></@myMacro><@myMacro></@>),则不会删除空白。现在在这些情况下也将删除空白。) ,现在将忽略夹在两个非输出元素(例如宏定义,赋值,导入或属性设置)之间的空格。更多信息:模板作者指南/其他/空白处理/空白剥离

  • function指令现在用于定义方法。您应该在旧模板中用macro替换function。但是请注意,如果您不使用return指令,而是使用不推荐使用的call指令调用它们,那么旧的function -s 仍然可以使用。

  • 表达式asinusing现在是模板语言中的关键字,如果没有方括号语法,则不能用作顶级变量名。如果有机会使用这些名称之一的顶级变量,则必须将其重命名,或将方括号语法与.vars特殊变量:.vars["in"]一起使用。

  • 内置的?new是一个安全漏洞。现在,它仅允许您实例化实现freemarker.template.TemplateModel接口的 java 对象。如果您希望?new内置功能具有以前版本中已有的功能,请为模板提供freemarker.template.utility.ObjectConstructor类的实例。 (例如:myDataModel.put("objConstructor", new ObjectConstructor());,然后在模板中可以执行此操作:<#assign aList = objConstructor("java.util.ArrayList", 100)>)

  • 更改为FreemarkerServlet

  • FreemarkerServlet默认使用ObjectWrapper.DEFAULT_WRAPPER而不是ObjectWrapper.BEANS_WRAPPER。这意味着默认情况下,类型java.lang.Stringjava.lang.Numberjava.util.Listjava.util.Map的对象将分别通过SimpleScalarSimpleNumberSimpleSequenceSimpleHash类包装为TemplateModels。因此,这些对象上的 java 方法将不可用。 FreeMarker 2.3 中的默认包装器实现自动知道如何包装 Jython 对象,并且还将org.w3c.dom.Node对象包装到freemarker.ext.dom.NodeModel的实例中。

    • FreemarkerServlet基本实现不再推论用于HttpRequest.getLocale()的模板的语言环境。相反,它只是委托给新的受保护方法deduceLocale。此方法的默认实现只是返回locale设置的配置值。

FTL 方面的更改

  • 字符串 Literals 内插。为了方便起见,现在在字符串 Literals 中支持插值。例如:<@message "Hello ${user}!" /><@message "Hello " + user + "!" />相同

  • 原始字符串 Literals:在以r为前缀的字符串 Literals 中,插值和转义序列不会被解释为特殊标记。例如:r"\n${x}"将简单解释为字符序列'\''n''$''{''x''}',而不是换行符和x变量的值。

  • 可以使用function指令在 FTL 中定义方法变量。

  • 支持可变数量的宏参数。如果宏声明中的最后一个参数以...结尾,则传递给宏的所有其他参数都可以通过该参数使用。对于使用位置参数调用的宏,该参数将是一个序列。对于命名参数,该参数将为哈希。请注意,它们也都适用于新的function指令。

  • 一个新的标题参数strip_text,它从模板中删除所有顶级文本。这对于“包含文件”来抑制分隔宏定义的换行符很有用。见ftl directive

  • 新的special variable.vars。这对于读取带有方括号语法的顶级变量很有用,例如.vars["name-with-hyphens"].vars[dynamicName]

  • macro和赋值指令现在可以接受带引号语法的任意目标变量名称。例如:<#macro "name-with-hyphens">...<#assign "foo bar" = 123>

  • 内置?keys?values哈希现在返回序列。实际上,这意味着您可以按索引访问它们的大小或检索其子变量,并使用所有sequence built-ins。 (给程序员的注意事项:TemplateHashModelEx接口尚未更改.您的旧代码将可用.请参阅 API 文档以了解原因.)

  • 现有的内置插件(?default?exists等)现在也可以与序列子变量一起使用。阅读default内置文档以获取更多信息。

  • 现在,空格剥离现在比以前更加积极:如果行仅包含 FTL 标签,它将始终删除前导和尾随空格。 (如果标记是<#include ...>或具有空指令语法为<@myMacro/>的用户定义的指令标记(或等效标记<@myMacro></@myMacro><@myMacro></@>),则以前的空格不会被删除。现在在这些情况下,空格也会被删除。) ,现在将忽略用于分隔宏定义和/或分配的顶级空白。更多信息:模板作者指南/其他/空白处理/空白剥离

  • 可以使用nt指令为单行禁用空格剥离(对于 No Trim)。

  • 哈希可以使用+运算符连接。右侧哈希中的键优先。

  • Java 和 JavaScript 字符串转义的新内置函数:j_stringjs_string

  • 内置replacesplit现在支持不区分大小写的比较和正则表达式(仅 J2SE 1.4),以及一些其他新选项。有关更多信息,请参见here

  • 用于正则表达式匹配的新内置函数(仅 J2SE 1.4):matches

  • 新内置的eval,将字符串评估为 FTL 表达式。例如"1+2"?eval返回数字 3.

  • Java 和 JavaScript 字符串转义的新内置函数:j_stringjs_string

  • 用于读取语言环境设置值的新特殊变量:localelang。查看更多在参考中...

  • 读取 FreeMarker 版本号的新特殊变量:version。查看更多在参考中...

  • 引入了树新指令recursevisitfallback,以支持声明性节点树处理。它们通常(尽管不是排他性地)用于处理 XMLImporting。同时,引入了新的变量类型,即节点类型。有关更多详细信息,请参见关于声明式 XML 处理的章节

  • 内置的?new是一个安全漏洞。现在,它仅允许您实例化实现freemarker.template.TemplateModel接口的 java 对象。如果您希望?new内置功能具有以前版本中已有的功能,请为模板提供freemarker.template.utility.ObjectConstructor类的实例。 (例如:myDataModel.put("objConstructor", new ObjectConstructor());,然后在模板中可以执行此操作:<#assign aList = objConstructor("java.util.ArrayList", 100)>)

  • 变量名称可以在任何地方包含@(不使用引号括弧语法)。例如:<#assign x@@@ = 123>是有效的。

  • 表达式asinusing现在是模板语言中的关键字,如果没有方括号语法(如.vars["in"]),则不能用作顶级变量名。

  • ftl directive的新参数:attributes。此属性的值是将任意属性(名称/值对)与模板相关联的哈希。属性的值可以是任何类型(字符串,数字,序列等)。 FreeMarker 不会尝试理解属性的含义。这取决于封装 FreeMarker 的应用程序(作为 Web 应用程序框架)。因此,允许的属性集及其语义取决于应用程序(Web 应用程序框架)。

  • 其他轻微的质量改进...

Java 方面的更改

  • 更加智能的默认对象包装:默认对象包装器现在为freemarker.template.DefaultObjectWrapper,这回落为使用freemarker.ext.beans.BeansWrapper将任意对象包装为 bean。同样,它将使用新的 DOM 包装器包装org.w3c.dom.Node对象。另外,它知道 Jython 对象,如果传入的对象是 Jython 对象,它将使用freemarker.ext.jython.JythonWrapper。 (我们认为这是向后兼容的更改,因为此新对象包装器仅以旧包装器无法包装的那些对象不同的方式包装,因此引发了异常.)

  • freemarker.template.TemplateMethodModel.exec现在返回Object而不是TemplateModel

  • strict_syntax设置的默认(初始)值已从false更改为true。当strict_syntaxtrue时,具有<include "foo.ftl">的旧语法的标记将被视为静态文本(因此它们像 HTML 标记一样按原样转到输出),而不是 FTL 标记。此类标签必须重写为<#include "foo.ftl">,因为只有以<#</#<@</@开头的部分才算作 FTL 标签。或者,要恢复识别旧标记语法和新标记语法的旧过渡行为,必须将strict_syntax设置为falsecfg.setStrictSyntaxMode(false)。另外,对于单个模板,您可以通过以<#ftl strict_syntax=false>开头模板来强制执行旧的行为。 (有关为什么严格语法比旧语法read this...更好的更多信息)

  • 新的CacheStorage实现:freemarker.cache.MruCacheStorage。该缓存存储实现了两级“最近使用”缓存。在第一级中,强烈引用项目直到指定的最大值。当超过最大值时,最近最少使用的项目将被移到第二级缓存中,在此对其进行软引用,直至达到另一个指定的最大值。 freemarker.cache.SoftCachseStorageStrongCachseStorage被优先使用,而MruCachseStorage则在各处使用。现在,默认的高速缓存存储是一个MruCachseStorage对象,其大小为 0,软大小为无限。 cache_storageConfiguration.setSetting现在将字符串值理解为"strong:200, soft:2000"

  • 对于BeansWrapper生成的模型,您现在可以使用${obj.method(args)}语法调用返回类型为void的方法。 void方法现在返回TemplateModel.NOTHING作为其返回值。

  • freemarker.template.SimpleHash现在可以包装只读的Map -s,例如 Servlet API 中的 HTTP 请求参数 Map。

  • 引入了TemplateNodeModel接口以支持对节点树的递归处理。通常,这将用于 XML。

  • 新包装:freemarker.ext.dom。它包含新的 XML 包装器,该包装器支持使用访问者模式(即<#visit ...>和类似指令)处理 XML 文档,并提供更方便的 XML 遍历作为旧版包装器。有关更多详细信息,请参见XML 处理指南

  • 新包装:freemarker.core。大多数高级用户使用的类已从freemarker.template包中移到了这里。 freemarker.template软件包拆分的主要原因是,当我们为第三方工具(例如调试 API)引入 API 时,“maven”公共类和接口的数量增长过多。

  • 新包装:freemarker.debug。这提供了调试 API,您可以通过它通过网络(RMI)调试执行模板。您必须编写前端(Client 端),因为 API 只是服务器端。有关更多信息,请阅读freemarker.debug软件包的 JavaDoc。

  • 您可以使用静态方法Configuration.getVersionNumber()查询 FreeMarker 版本号。另外,freemarker.jar中包含的Manifest.mf现在包含 FreeMarker 版本号,此外,使用java -jar freemarker.jar执行它会将版本号打印到标准输出中。

  • 添加了一个新的受保护的FreemarkerServlet方法:Configuration getConfiguration()

  • 日期支持现在标记为最终支持。 (之前是实验性的.)

  • BeansWrapper进行了改进,以防止自省时出现某些安全异常。

  • 其他次要质量改进和扩展...

Other changes

  • 手册和 JavaDoc API 中的修复和改进。

最终版本之前的发行记录

最终版本和候选版本 4 之间的差异

  • 添加了一个新的特殊变量以打印 FreeMarker 版本号:version。查看更多在参考中...

  • 次要文档修复和改进。

版本候选 4 和版本候选 3 之间的差异

  • BeansWrapper进行了改进,以防止自省时出现某些安全异常。

  • FreemarkerXmlTask有两个新的子任务,可用于准备使用 Jython 脚本执行模板:prepareModelprepareEnvironmentjython子任务现已弃用,其作用与prepareEnvironment相同。有关更多详细信息,请参见 Java API 文档。

  • 读取 FreeMarker 版本号的新特殊变量:version。查看更多在参考中...

  • 错误修正:大于号不会再混淆内置的eval了。

  • 错误修正:BeansWrapper现在正确包装了方法的null返回值。

  • 错误修正:FreemarkerXmlTask不再需要 Jython 类,除非您真的使用 Jython 脚本。 Jython 相关功能中的其他几个错误修复。

  • 错误修正:如果模板异常处理程序忽略了该异常,则 FTL 标签(例如<#if "foo${badVar}" != "foobar">)内插值中发生的错误的处理方式与 FTL 标签外插值中发生的错误的处理方式相同。因此,不会跳过指令调用,而有问题的插值将替换为空字符串。 (这与<#if "foo"+badVar != "foobar">的行为不一致,该行为应与上一个示例 100%等效.)

  • 错误修正:FileTemplateLoader现在收到根据本机文件系统格式错误的路径时,功能更强大。在较早的版本中,此 Classpath 有时会导致意外的IOException,当您使用MultiTemplateLoader时,它们会中止在进一步的FileTemplateLoader -s 中搜索模板。

版本候选 3 和版本候选 2 之间的差异

  • 错误修正:修复了由最新的高速缓存错误修正引入的模板高速缓存中的致命错误。在经过更新延迟后,模板缓存始终会重新加载未更改的模板,直到实际更改了模板为止,在这种情况下,模板缓存再也不会重新加载模板了。

版本候选 2 和版本候选 1 之间的差异

  • 错误修正:当模板缓存被旧版本替换时,它没有重新加载模板。

  • API JavaDoc 修复:与日期/时间相关的类/接口被标记为实验性的。他们不是实验性的。

  • 较小的网站改进。

候选版本 1 和预览版 16 之间的差异

  • 警告!非向后兼容更改! strict_syntax设置的默认(初始)值已从false更改为true。当strict_syntaxtrue时,具有<include "foo.ftl">的旧语法的标记将被视为静态文本(因此它们像 HTML 标记一样按原样转到输出),而不是 FTL 标记。此类标签必须重写为<#include "foo.ftl">,因为只有以<#</#<@</@开头的部分才算作 FTL 标签。或者,要恢复识别旧标记语法和新标记语法的旧过渡行为,必须将strict_syntax设置为falsecfg.setStrictSyntaxMode(false)。另外,对于单个模板,您可以通过以<#ftl strict_syntax=false>开头模板来强制执行旧的行为。 (有关为什么严格语法比旧语法read this...更好的更多信息)

  • ftl directive的新参数:attributes。此属性的值是将任意属性(名称/值对)与模板相关联的哈希。属性的值可以是任何类型(字符串,数字,序列等)。 FreeMarker 不会尝试理解属性的含义。这取决于封装 FreeMarker 的应用程序(作为 Web 应用程序框架)。因此,允许的属性集及其语义取决于应用程序(Web 应用程序框架)。

  • 错误修正:freemarker.template.utility.DeepUnwrap将序列解包为空ArrayList -s。

  • 错误修正:如果您包含/导入了路径为*/的模板(获取),而该模板本身又包含/导入了路径为*/的另一个模板,则可能会失败。

  • freemarker.core.Environment的新方法:importLib(Template loadedTemplate, java.lang.String namespace)getTemplateForImporting(...)getTemplateForInclusion(...)

  • 改进了includeimport指令的java.io.IOException相关错误消息。

  • 文档中的较小改进。

Preview 16 和 Preview 15 版本之间的差异

  • 新包装:freemarker.debug。这提供了调试 API,您可以通过它通过网络(RMI)调试执行模板。您必须编写前端(Client 端),因为 API 只是服务器端。有关更多信息,请阅读freemarker.debug软件包的 JavaDoc。 (调试 API 出现了一段时间,只是我忘了在版本历史 Logging 宣布它.很抱歉.)

  • 错误修正:使用新的 XML 包装器@@markup和类似的特殊键:

  • 已为空元素返回<foo></foo>而不是<foo />。除了不必要的冗长之外,如果生成 HTML,它会使浏览器感到困惑。

    • 已经显示了原始文档中没有明确给定值的属性,而 DTD 只是一个默认值。

    • 忘记在<!DOCTYPE ...>中的系统标识符之前放置空格。

  • 错误修正:如果上下文是一个空节点集,带有 Jaxen 的 XPath 已死于NullPointerException

  • 更智能的 Xalan XPath 错误消息。

  • 从模板缓存中撤消了对类加载器的后备逻辑。

  • 从现在开始,如果没有 XPath 引擎可用,并且没有 XPath 也无法解释 XML 查询中的哈希键,那么错误将清楚地表明这一点,而不是默默地返回未定义的变量(空)。

  • 错误修正:一些模板导致解析器死亡。

  • 到处都有其他一些小的改进...

Preview 15 和 Preview 14 版本之间的差异

  • 错误修正:新的默认模板缓存存储(MruCacheStorage)从随机时间点开始一直以NullPointerException连续失败,通常是在 JVM 中内存使用率很高时。

  • 错误修正:在错误消息中,当带引号的 FTL 指令具有嵌套内容时,该内容也会被加引号,因此引号可能会很长并且不必要地暴露嵌套行。

预览版 14 和预览版 13 之间的差异

  • freemarker.template.TemplateMethodModel.exec现在返回Object而不是TemplateModel

  • 带有 Jaxen(不是 Xalan)的 XPath 的修复和改进。非节点设置的 XPath 表达式现在可以使用。可在带有 XPath 变量引用(例如doc["book/chapter[title=$currentTitle]"])的 XPath 表达式中访问 FreeMarker 变量。

  • freemarker.cache.SoftCachseStorageStrongCachseStorage被选中。到处都使用更灵活的MruCachseStorage。现在,默认的缓存存储是一个MruCachseStorage对象,其大小为 0,软大小为无限。 Configuration.setSetting表示cache_storage现在将字符串值理解为"strong:200, soft:2000"

  • 错误修正:freemarker.cache.MruCachseStorage有时与ClassCastException一起死亡。

  • Java 和 JavaScript 字符串转义的新内置函数:j_stringjs_string

  • freemarker.template.TemplateExceptionHandler.HTML_DEBUG_HANDLER现在可以打印更多 HTML 上下文验证消息。

  • 您可以使用静态方法Configuration.getVersionNumber()查询 FreeMarker 版本号。另外,freemarker.jar中包含的Manifest.mf现在包含 FreeMarker 版本号,此外,使用java -jar freemarker.jar执行它会将版本号打印到标准输出中。

  • 添加了一个新的受保护的FreemarkerServlet方法:Configuration getConfiguration()

  • 错误修正:FreeMarker 在某些情况下冻结在空的条件块上。

  • 错误修正:方法使用list指令在对象上调用两次,如parent.getChildren()<#list parent.children as child> ...</#list>

预览 13 和预览 12 版本之间的差异

  • 现在,空格剥离现在比以前更加积极:如果行仅包含 FTL 标签,它将始终删除前导和尾随空格。 (如果标记是<#include ...>或具有空指令语法为<@myMacro/>的用户定义的指令标记(或等效标记<@myMacro></@myMacro><@myMacro></@>),则以前的空格不会被删除。现在在这些情况下,空格也会被删除。) ,现在将忽略用于分隔宏定义和/或分配的顶级空白。更多信息:模板作者指南/其他/空白处理/空白剥离

  • 可以使用nt指令为单行禁用空格剥离(对于 No Trim)。

  • 声明性 XML 处理的新指令:fallback

  • freemarker.template.SimpleHash现在可以包装只读的Map -s,例如 Servlet API 中的 HTTP 请求参数 Map。

Preview 12 和 Preview 11 版本之间的差异

此版本与先前的预览版本之间的唯一变化是,Preview 11 有一个错误,即绝不会收集 DOM 树。

Preview 11 和 Preview 10 版本之间的差异

  • 许多与 XML 相关的更改。其中一些与先前的预览版本不兼容!有关 XML 相关功能现在如何工作的更详细说明,请参阅:XML 处理指南

  • 注意!现在,诸如foo.@bar之类的属性查询返回序列(类似于子元素查询和 XPath 查询),而不是单个节点。由于规则具有大小为 1 的节点序列,因此编写${foo.@bar}仍然很好,但是诸如?exists?if_exists?default之类的内置对象无法像以前那样工作。例如,您现在必须写foo.@bar[0]?default('black')而不是foo.@bar?default('black')。因此,如果您将存在内置属性与属性一起使用,则必须在模板中找到这些出现的位置并添加[0]

    • 注意! XML 名称空间处理已经完全 Rewrite,并且与 pre 10 完全不兼容。如果您的 XMLImporting 文档都不使用xmlns属性,请不要担心。不过,担心的是,如果您使用的是“宽松模式”,则只比较元素的本地名称,因为现在已经不存在了。抱歉...

    • 注意!现在,特殊键@@@*返回一个属性节点序列,而不是它们的哈希。

    • 现在,一些哈希键可用于存储多个节点的节点序列。例如,要获取所有chapter -s 的所有para元素的列表,只需编写doc.book.chapter.para即可。或者,要获取所有chapter -s 的标题属性列表,请写入doc.book.chapter.@title

    • 新的特殊哈希键:**@@start_tag@@end_tag@@attribute_markup@@text@@qname

    • 现在,属性节点的?parent返回属性节点所属的元素节点。

    • 如果您一次调用静态freemarker.ext.dom.NodeModel.useJaxenXPathSupport()方法,则可以使用 Jaxen 代替 Xalan 来使用 XPath 表达式。我们计划自动使用 Jaxen 而不是 Xalan(如果有的话),只是 Jaxen 支持尚未完全起作用。

  • 新的特殊变量:.vars。这对于读取带有方括号语法的顶级变量很有用,例如.vars["name-with-hyphens"].vars[dynamicName]

  • 新内置的eval,将字符串评估为 FTL 表达式。例如"1+2"?eval返回数字 3.

  • FreemarkerServlet现在使用配置的locale设置而不是Locale.getDefault()来设置模板的语言环境。此外,deduceLocale方法的签名已更改。

  • 我们有一个新的(测试版状态)CacheStorage实现:freemarker.cache.MruCacheStorage。该缓存存储实现了两级“最近使用”缓存。在第一级中,强烈引用项目直到指定的最大值。当超过最大值时,最近最少使用的项目将被移到第二级缓存中,在此对其进行软引用,直至达到另一个指定的最大值。您可以使用cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(maxStrongSize, maxSoftSize))进行尝试。

预览版 10 和预览版 9 之间的差异

  • 出于特殊目的,出于相同目的使用新的 FTL 指令<#xmlns...>,删除了特殊键@@xmlns

  • 默认情况下,系统对名称空间前缀的使用更加严格。通常,必须使用前缀来限定与 XML nampespace 关联的子元素。您可以使用新的<#xmlns...>指令来执行此操作,但是在 ImportingXML 文档中声明的前缀实际上无需声明即可使用。

  • 引入了一个名为@@text的新特殊键,该键返回(递归)包含在一个元素中的所有文本节点,这些文本节点全部串联在一起。

  • Jaxen 或 Xalan 均可用于提供 XPath 功能。以前的版本仅适用于 Xalan。

  • FreemarkerServlet默认使用ObjectWrapper.DEFAULT_WRAPPER而不是ObjectWrapper.BEANS_WRAPPER。这意味着默认情况下,类型java.lang.Stringjava.lang.Numberjava.util.Listjava.util.Map的对象将分别通过SimpleScalarSimpleNumberSimpleSequenceSimpleHash类包装为TemplateModels。因此,这些对象上的 java 方法将不可用。 FreeMarker 2.3 中的默认包装器实现自动知道如何包装 Jython 对象,并且还将org.w3c.dom.Node对象包装到freemarker.ext.dom.NodeModel的实例中。

  • FreemarkerServlet基本实现不再从 HttpRequest.getLocale()钩子中推断出要使用的语言环境。相反,它只是委托给子类中可重写的deduceLocale()钩子。基本实现只使用Locale.getDefault()

Preview 9 和 Preview 8 版本之间的差异

  • 修复了预览 8 中引入的错误:XPath,@@markup@@nested_markup现在可用于文档节点。

Preview 8 和 Preview 7 版本之间的差异

  • macro和赋值指令现在可以接受带引号语法的任意目标变量名称。例如:<#macro "foo-bar">...<#assign "this+that" = 123>。这很重要,因为 XML 元素名称可以包含连字符,并且到目前为止,无法为这些元素定义处理程序宏。

  • 特殊键@@content重命名为@@nested_markup

  • 修复了与 XML 相关的过时的手册部分(即使在 Preview 7 中也已过时)。

  • 更好地解析错误消息。

  • 这里和那里的小错误修正...

Preview 7 和 Preview 6 版本之间的差异

  • XPath 查询的缓存至少在大量使用 XPath 的情况下应该可以显着提高 XML 处理的性能。

  • XML 处理功能中对 XML 命名空间的处理方面的改进。 2.3pre6 中引入的新strict_namespace_handling设置已删除。达成了一个通用解决方案,该解决方案应使该配置设置不再必要。

  • 特殊键@xmlns重命名为@@ xmlns。保留的名称空间前缀default已重命名为@@default

  • ftl指令现在接受非字符串类型。

  • 在 freemarker.ext.dom 包中为 XML 节点包装器引入了新的特殊键。 @@markup键返回组成该元素的 Literals 标记,而@@content键返回除开始和结束标记之外的所有元素标记。

  • 这里和那里的小错误修正...

Preview 6 和 Preview 5 版本之间的差异

  • 现在,内置的内置对象(?default?exists等)也可以与序列子变量一起使用。阅读默认内置文档以获取更多信息。

  • 内置matches现在返回一个序列而不是一个集合。

  • XML 处理功能中对 XML 命名空间的处理方面的改进。引入了新设置strict_namespace_handling。如果设置了此选项(默认情况下为关闭状态),则用于访问/递归机制的任何节点处理宏都必须来自宏库,该宏库在其 ftlHeaders 中声明其处理了相关的名称空间。

  • 这里和那里的小错误修正...

Preview 5 和 Preview 4 版本之间的差异

  • 内置replacesplit现在支持不区分大小写的比较和正则表达式(仅 J2SE 1.4)以及一些其他新选项。有关更多信息,请参见here

  • 用于正则表达式匹配的新功能(仅 J2SE 1.4):matches

  • 这里和那里的小错误修正...

  • 手册:更多浏览器安全的 HTML-s。更多更新的内容。

Preview 4 和 Preview 3 版本之间的差异

  • 错误修正:使用多类型变量时,哈希类型的+运算符重载的优先级高于某些较早的重载的优先级。

  • 发行版tar.gz中缺少 API 文档。

Preview 3 和 Preview 2 版本之间的差异

  • XML 处理:许多各种错误修正,尤其是声明式处理。

  • XML 处理:内置的namespace_urixmlnsuriHeaders 参数和TemplateNodeModel.getNodeNamespace方法分别重命名为node_namespacegetNodeNamespace

  • XML 处理:更好的文档。特别是,请注意:XML 处理指南

  • 一个新的标题参数strip_text,它从模板中删除所有顶级文本。见ftl directive

  • 支持可变数量的宏参数。如果宏声明中的最后一个参数以...结尾,则传递给宏的所有其他参数都可以通过该参数使用。对于使用位置参数调用的宏,该参数将是一个序列。对于命名参数,该参数将为哈希。

  • 对于BeansWrapper生成的模型,您现在可以使用${obj.method(args)}语法调用返回类型为void的方法。 void方法现在返回TemplateModel.NOTHING作为其返回值。

预览 2 和预览 1 版本之间的差异

  • freemarker.ext.dom.NodeModel API 稍有变化。 setDocumentBuilder()方法更改为setDocumentBuilderFactory(),因为较旧的方案不是线程安全的。 stripCommentsstripPIs方法重命名为removeCommentsremovePIs,并且现在已修复。添加了新方法simplify

  • 表达式asinusing现在是模板语言中的关键字,如果没有方括号语法(如.vars["in"]),则不能用作顶级变量名。如果有机会使用这些名称之一的顶级变量,则必须将其重命名(或使用方括号语法)。抱歉给你带来不便。

  • 内置的?new是一个安全漏洞。现在,它仅允许您实例化实现freemarker.template.TemplateModel接口的 java 对象。如果您希望?new内置功能具有以前版本中已有的功能,请为模板提供新freemarker.template.utility.ObjectConstructor类的实例。

  • <#recurse>指令已损坏。它不适用于using子句。现在,此问题已解决。