2.2

Page Contents

发布日期:2003-03-27

此版本引入了一些非常重要的新功能。不幸的是,进化又一次痛苦。我们有一些非向后兼容的更改(请参见下文)。另外,对于那些正在 await 所需的本机日期/时间类型的人,对不起,它仍然不在这里(由于团队内部出现一些混乱,请耐心 await,即将到来)。

非向后兼容的更改!

  • 宏现在是普通变量。这意味着如果您很不幸,并且您同时具有一个宏和另一个具有相同名称的变量,那么该变量将覆盖该宏,因此您的旧模板将发生故障。如果您有一组公共宏,则应使用新的namespace feature来防止与模板中使用的变量发生意外冲突。

  • 随着新的namespace support的引入,globalassign指令不再是同义词。 assign在当前namespace中创建一个变量,而global创建在所有命名空间中可见的变量(就像该变量将在数据模型中一样)。因此,使用assign创建的变量更具体,并且隐藏使用global创建的同名变量。结果,如果您在模板中的同一变量中同时使用了globalassign,则它们将出现故障。解决方案是用assign搜索并替换旧模板中的所有global

  • 保留的哈希root不再作为 sched 义变量存在(我们不再具有保留的变量)。使用特殊变量表达式可以达到类似的效果。但是,由于命名空间的引入导致变量范围的变化,因此我们无法等效地替代root。您可能应该使用.globals.namespace

  • BeansWrapper不再将本地 Java 数组,布尔值,数字,枚举,迭代器和资源包公开为TemplateScalarModel。这样,通过BeansWrapper包裹的数字对象将受 FreeMarker 的数字格式化机制的约束。同样,可以使用内置的?string格式化布尔值。

  • Configuration.setServletContextForTemplateLoading的签名已更改:第一个参数现在是Object而不是javax.servlet.ServletContext。因此,您必须重新编译调用此方法的类。当javax.servlet类不可用并且您不会调用此方法时,需要进行更改以防止类加载失败。

  • 此版本引入了一个解析时间空白去除器,该解析时间空白去除器去除了 FreeMarker 标签和 Comments 周围的一些典型多余空白。 *此功能默认情况下处于启用状态!*如果生成 HTML 等空白中性输出,则很可能不会造成问题。但是,如果确实在生成的输出中引起不希望的重新格式化,则可以使用config.setWhitespaceStripping(false)禁用它。另外,您可以使用新的ftl指令在每个模板的基础上启用/禁用它。

  • 引入了一些新的指令:nestedimportescapenoescapetrtlt。这意味着,如果您很不幸,并且模板的文本中包含类似<nested>的内容,那么它将被误解为指令。为了将来避免这种问题,我们建议大家从旧语法切换到新语法(“严格语法”)。无论如何,严格语法将是从某些更高版本开始的默认语法。我们计划发布一种转换工具,用于转换旧模板。有关更多信息,请阅读:模板语言参考/不建议使用的 FTL 构造/旧的 FTL 语法

  • FreemarkerServlet创建的数据模型现在使用自动作用域发现,因此不再必须写入Application.attrNameSession.attrNameRequest.attrName;只需写attrName(有关更多信息read this)。如果依赖某些顶级变量的不存在,这可能会破坏旧模板。

  • FreemarkerServlet现在将模板文件的编码用于输出,除非您在ContentType init-param 中指定了编码,例如text/html; charset=UTF-8

  • 现在,模板路径的格式比以前更加受限制。路径不得使用/./以及../://以及 URL 路径(或 UN * X 路径)中的其他含义。字符*?保留。另外,模板加载器一定不要使用以/开头的路径。有关更多信息,请阅读:程序员指南/配置/模板加载

  • 到目前为止,如果在不使用参数的情况下调用TemplateTransformModel.getWriter,则将其作为参数 Map 接收到空值。从现在开始,它将收到一个空的 Map。请注意,以前的 API 文档没有说明如果没有参数,则它总是会收到 null,因此,绝望的只有极少数的类会利用此设计错误。

FTL(FreeMarker 模板语言)的更改

  • 用户定义的指令:转换和宏调用语法已统一;可以用与用户定义的指令相同的方式调用它们。这也意味着宏支持命名参数和嵌套内容(就像现在不建议使用的transform指令那样)。例如,如果您有一个名为sect的宏,则可以通过<@sect title="Blah" style="modern">Blah blah...</@sect>进行调用。有关更多信息,请阅读:模板作者指南/其他/定义自己的指令

  • 宏现在是普通变量。这大大简化了 FreeMarker 的语义,同时提供了更大的灵 Active。例如,您可以将宏作为参数传递给其他宏和转换。至于将常用的宏和变量名冲突的问题,我们提供了一个更强大的解决方案:名称空间。

  • 命名空间:如果您要汇编宏和转换(和其他变量)的集合(“库”),然后在任何模板中使用它们,而不必担心与应用程序特定和临时变量的意外名称冲突,则名称空间是无价的。与您要在同一模板中使用的其他集合的变量。如果 FreeMarker 用户想要共享其宏/转换集合,那么这非常重要。有关更多信息,请阅读:模板作者指南/其他/命名空间

  • 随着名称空间的引入,与变量相关的术语发生了变化。结果,assign不再与global同义。 assign指令已被弃用,几乎在所有地方都应使用它代替global。在新方法中,assign在当前名称空间中创建变量,而global创建在所有名称空间中可见的变量(就像该变量位于数据模型的根中一样)。在当前名称空间中使用assign创建的变量将隐藏与global创建的同名变量。

  • ftl指令:使用此指令,您可以提供有关 FreeMarker 模板的信息,例如模板的编码(字符集),使用的 FTL 语法变体等。此外,此指令还可以帮助您编写对 FreeMarker 配置的依赖性较小的模板。设置,还可以帮助第三方工具识别并正确解析 FreeMarker 模板。有关更多信息,请参见:ftl directive

  • 空格剥离:FreeMarker 现在会自动删除 FreeMarker 标签和 Comments 周围的一些典型多余的空白,例如<#if ...>标签之前的缩进空格和换行符。有关更多信息,请阅读:模板作者指南/其他/空白处理/空白剥离

  • 将通用(“转义”)表达式应用于块中所有插值的新指令:escape。该名称来自此指令在插值的 HTML 自动转义中的常用用法。

  • 内置string的数字格式化的新方法是foo?string(format),而不是不太自然的foo?string[format]

  • 内置string可用于布尔值。例如:${spamFilter?string("enabled", "disabled")}。有关更多信息阅读参考

  • 可以使用boolean_format设置来设置使用string内置输出布尔值的默认字符串。

  • Comments 可以放在 FTL 标签和插值中。例如:<#assign <#-- a comment --> x = 3>

  • 所有字母和数字均以变量名启用,也允许$(与 Java 编程语言一样)。因此,您可以使用重音符号,阿拉伯字母,中 Literals 母等。

  • 字符串 Literals 可以用撇号引起来。 "foo"'foo'是等效的。

  • 新的string built-insindex_oflast_index_ofstarts_withends_withreplacesplitchop_linebreakuncap_first

  • 新的sequence built-inssortsort_by

  • 新的内置函数供 maven 检查变量的类型。看到:is_... built-ins

  • 新的内置函数供 maven 创建某些 Java TemplateModel实现的变量。看到:new built-in

  • 新的内置namespace,用于获取宏的名称空间。

  • 新的表达式类型:特殊变量表达式。为了防止在向后兼容时引入新的 sched 义变量,现在使用特殊变量表达式来访问它们。

  • 新指令:trtlt指令使您可以在极端 FTL 应用程序中进行显式空格删除。有关更多信息,请阅读the reference

  • 现在,assignlocalglobal可以捕获将嵌套模板片段生成的输出生成到变量中。这不赞成capture_output转换。更多信息:分配指令参考

  • 批量分配(如<#assign x=1, y=2, z=3>)不再需要冒号来分隔分配(如<#assign x=1 y=2 z=3>),尽管仍然允许保留向后兼容性。

  • 包含//:的路径被视为绝对路径。

  • includetransform指令不再需要使用分号从参数列表中分离模板或转换名称,尽管仍然可以保留其向后兼容性。

  • # -less 标记语法已弃用(但仍然有效)。也就是说,您应该写<#directive ...>而不是<directive ...>,并写</#directive ...>而不是</directive ...>。有关更多信息,请阅读:模板语言参考/不建议使用的 FTL 构造/旧的 FTL 语法

  • foreach已贬值(但仍然有效)。请改用list

  • 错误修正:哈希和序列构造函数(如[a, b, c])中未定义的变量未引起错误。

  • 错误修正:如果有多个串联链接,则字符串串联存在性能问题,例如:"a"+x+"a"+x+"a"+x+"a"+x+"a"+x

Java 方面的更改

  • 可以在FreemarkerServlet驱动的模板中将任意 JSP 自定义标记用作 FreeMarker 转换。更多信息:程序员指南/其他/将 FreeMarker 与 servlet 一起使用

  • BeansWrapper的各种改进:

  • BeansWrapper不再将任何对象公开为TemplateScalarModel,仅公开了java.lang.StringCharacter对象。这样,通过BeansWrapper包裹的数字对象将受到 FreeMarker 的数字格式化机制的约束。副作用是,以前在相等和不相等运算中接受的非字符串和非数字对象(因为它们具有字符串表示形式)现在将导致引擎在尝试比较时引发异常。

    • java.lang.Character对象通过BeansWrapper作为标量公开。

    • 实验性功能:使用BeansWrappersetSimpleMapWrapper方法,可以将其配置为将java.util.Map -s 包装为TemplateHashModelEx -s,并且不公开对象的方法。

  • TransformControl接口(之前是实验性的):如果TemplateTransformModel.getWriter返回的Writer实现了此接口,则它可以指示引擎跳过或重复对嵌套内容的评估,并获得有关嵌套内容评估期间引发的异常的通知。请注意,现在允许onStartafterBody方法抛出IOException。有关更多信息,请阅读 API 文档。

  • 可以使用新的Configuration方法禁用本地化查找:set/getLocalizedLookupclearTemplateCache

  • 新界面freemarker.cache.CacheStorage允许用户使用cache_storage设置插入自定义模板缓存策略。现在,核心软件包附带了两种实现:SoftCacheStorageStrongCacheStorage。有关更多信息,请阅读:程序员指南/配置/模板加载

  • 您可以使用Configurable个超类的新setSetting(String key, String value)方法(如Configuration)来设置字符串名称和字符串值的设置。您也可以使用setSettings方法从.properties文件中加载设置。

  • 其他新的Configuration方法:clearTemplateCacheclearSharedVariablesgetTemplateLoaderclone

  • 更改为TemplateTransformModel界面:getWriter可以抛出IOException,如果转换不支持主体内容,则可以返回null

  • 到目前为止,如果在不使用参数的情况下调用TemplateTransformModel.getWriter,则将其作为参数 Map 接收到空值。从现在开始,它将收到一个空的 Map。请注意,以前的 API 文档没有说明如果没有参数,则它总是会收到 null,因此,绝望的只有极少数的类会利用此设计错误。

  • FreemarkerServlet的各种改进:

  • 数据模型现在使用自动作用域发现,因此不再必须编写Application.attrNameSession.attrNameRequest.attrName;写attrName就足够了。有关更多信息read this

    • FreemarkerServlet现在将模板文件的编码用于输出,除非您在ContentType init-param 中指定了编码,例如text/html; charset=UTF-8

    • 可以通过 Servlet 初始化参数(template_exception_handlerlocalenumber_format等)设置所有Configuration级别的设置。

    • 现在将 servlet 内部使用的对象包装器设置为其Configuration实例的默认对象包装器。

    • 它不再强制为不属于现有会话的请求创建会话,从而提高了可伸缩性。

  • 与 JDOM 无关的 XML 包装:freemarker.ext.xml.NodeListModel是不依赖 JDOM 的freemarker.ext.jdom.NodeListModel的重新实现;您不再需要 JDOM .jar。新的NodeListModel自动使用 W3C DOM,dom4j 或 JDOM,具体取决于可用的库(即,取决于将什么对象传递给其构造函数)。

  • 错误修正:WebappTemplateLoader:由于资源缓存,模板更新无法与 Tomcat 一起正常使用。现在WebappTemplateLoader尝试以File的身份直接访问资源,如果可能的话,因此绕过了缓存。

  • FreemarkerServlet的各种错误修复:

  • 如果通过RequestDispatcher.include调用,则 servlet 现在将加载正确的模板。

    • HttpServletRequest对象的缓存现在符合 Servlet 规范。

    • TemplateException s 在某些情况下被抑制,导致页面半渲染而没有错误消息。

  • 错误修正:如果javax.servlet类不可用,则 FreeMarker 不起作用,因为Configuration明确引用javax.servlet.ServletContext

  • 错误修正:如果类仅在WEB-INF中可用,则可能找不到类,并且 FreeMarker 尝试动态加载该类。

  • 错误修正:Template构造函数(因此是Configuration.getTemplate)有时会抛出TokenMgrError(未经检查的异常)而不是ParseException

Other changes

  • 与 Web 应用程序相关的示例已被替换。

最终版本之前的发行记录

最终版本与 RC2 版本之间的差异

  • 您可以使用Configuration和其他Configurable子类的setSettings方法从.properties文件中加载设置。

  • 内置新字符串:uncap_first

  • 错误修正:将 XML 文档暴露于模板并使用 Jaxen 通过 XPath 访问它时,发生了ClassCastException

  • 错误修正:如果您不使用静态默认Configuration实例,则在某些情况下模板缓存已使用错误的Configuration实例加载了模板。

RC2 和 RC1 版本之间的差异

  • 非向后兼容更改!:FreemarkerServlet现在将模板文件的编码用于输出,除非您在ContentType init-param 中指定了编码,例如text/html; charset=UTF-8

  • 与 RC1!相比,不具有向后兼容的更改:capture_output转换在当前名称空间中使用var参数创建变量(作为assign指令),而不是全局变量。

  • 内置string的数字格式化的新方法是foo?string(format),而不是不太自然的foo?string[format]

  • 内置string可用于布尔值。例如:${spamFilter?string("enabled", "disabled")}。有关更多信息阅读参考

  • 可以使用boolean_format设置来设置使用string内置输出布尔值的默认字符串。

  • 字符串 Literals 可以用撇号引起来。 "foo"'foo'是等效的。

  • 新界面freemarker.cache.CacheStorage允许用户使用cache_storage设置插入自定义模板缓存策略。现在,核心软件包附带了两种实现:SoftCacheStorageStrongCacheStorage。有关更多信息,请阅读:程序员指南/配置/模板加载

  • 您可以使用Configurable个超类的新setSetting(String key, String value)方法(如Configuration)来设置字符串名称和字符串值的设置。

  • 其他新的Configuration方法:getTemplateLoaderclone

  • 现在,assignlocalglobal可以捕获将嵌套模板片段生成的输出生成到变量中。这不赞成capture_output转换。更多信息:分配指令参考

  • 其他新的Configuration方法:getTemplateLoaderclone

  • 更改为TemplateTransformModel界面:getWriter可以抛出IOException,如果转换不支持主体内容,则可以返回null

  • 到目前为止,如果在不使用参数的情况下调用TemplateTransformModel.getWriter,则将其作为参数 Map 接收到空值。从现在开始,它将收到一个空的 Map。请注意,以前的 API 文档没有说明如果没有参数,则它总是会收到 null,因此,绝望的只有极少数的类会利用此设计错误。

  • 更改为TemplateControl接口:现在允许onStartafterBody方法抛出IOException

  • 包含//:的路径被视为绝对路径。

  • 新的string built-insindex_oflast_index_ofstarts_withends_withreplacesplitchop_linebreak

  • 新的sequence built-inssortsort_by

  • 可以通过 Servlet 初始化参数(template_exception_handlerlocalenumber_format等)设置所有Configuration级别的设置。

  • 错误修正:如果类仅在WEB-INF中可用,则可能找不到类,并且 FreeMarker 尝试动态加载该类。

  • 错误修正:调用setTemplateLoader时,ConfigurationsetLocalizedLookup(false)被覆盖。

  • 错误修正:如果有多个串联链接,则字符串串联存在性能问题,例如:"a"+x+"a"+x+"a"+x+"a"+x+"a"+x

  • 错误修正:空格剥离不适用于跨多行的标签。

  • 错误修正:删除了对 JDK 1.3 的一些依赖关系,因此可以为 JDK 1.2.2 构建 FreeMarker。

Preview 2 和 RC1 版本之间的差异

  • ftl现在更加严格,并且不允许自定义参数。要将自定义属性与模板相关联,如果需要,我们可以稍后添加新的指令。

  • escape指令不再影响数字插值(#{...}),因为它已导致字符串转义为?html的错误。

  • freemarker.cache.TemplateLoadernormalizeName方法已删除,因为它引起了太多麻烦。相反,规范化发生在TempateCache中的单个点上。因此,FreeMarker 现在对模板路径的格式更加严格,因为/../之类的内容由内核解释。

  • 实验性功能:使用BeansWrappersetSimpleMapWrapper方法,可以将其配置为将java.util.Map -s 包装为TemplateHashModelEx -s,并且不公开对象的方法。

  • 新的Configuration方法:set/getLocalizedLookupclearTemplateCacheclearSharedVariables

  • Environment API 中的更多清理操作。

  • 更好地符合 JSP 标准:JSP 页面范围变量是在模板中创建的全局变量(而不是数据模型的变量)。

  • 与 JDOM 无关的 XML 包装:freemarker.ext.xml.NodeListModel是不依赖 JDOM 的freemarker.ext.jdom.NodeListModel的重新实现;您不再需要 JDOM .jar。新的NodeListModel自动使用 W3C DOM,dom4j 或 JDOM,具体取决于可用的库(即,取决于将什么对象传递给其构造函数)。

  • 错误修正:WebappTemplateLoader:由于资源缓存,模板更新无法与 Tomcat 一起正常使用。现在WebappTemplateLoader尝试以File的身份直接访问资源,如果可能的话,因此绕过了缓存。

  • 错误修正:模板更新延迟时间过去后(默认为 5 秒),即使模板文件未更改,也从模板缓存中删除了加载了MultiTemplateLoader个子类的模板。如果您有许多模板,或者模板更新延迟设置为 0 秒,这可能会为高流量服务器带来很多额外负载。

  • 错误修正:哈希和序列构造函数(如[a, b, c])中未定义的变量未引起错误。

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

  • 标识符和$字符(与 Java 编程语言一样)均允许使用所有 16 位 Unicode 字母和数字。因此,您可以在模板中使用带重音符号的字母,阿拉伯字母,中 Literals 母等作为标识符

  • 宏现在可以为嵌套内容创建循环变量。有关更多信息read this

  • 新指令:trtlt指令使您可以在极端 FTL 应用程序中进行显式空格删除。有关更多信息,请阅读the reference

  • 带有名称空间的分配的语法已从<#assign foo=123 namespace=myLib>更改为<#assign foo=123 in myLib>,因为先前的语法由于与批量分配的相似性而令人困惑。

  • 批量分配(如<#assign x=1, y=2, z=3>)不再需要冒号来分隔分配(如<#assign x=1 y=2 z=3>),尽管仍然允许保留向后兼容性。

  • 宏调用支持位置参数传递,这是普通命名参数传递的简写形式。有关更多详细信息,请阅读阅读参考

  • 新的内置namespace,用于获取当前正在执行的宏的名称空间。

  • TransformControl接口(之前是实验性的):如果TemplateTransformModel.getWriter返回的Writer实现了此接口,则它可以指示引擎跳过或重复对嵌套内容的评估,并获得有关嵌套内容评估期间引发的异常的通知。有关更多信息,请阅读 API 文档。

  • Jython 包装器现在可以包装任意的 Java 对象,而不仅仅是PyObject -s。如果将既不是TemplateModel也不是PyObject的对象传递给包装器,则首先使用 Jython 自己的包装机将其强制为PyObject,然后像其他PyObject一样包装为TemplateModel

  • Environment API 中的一些清理。

  • 与 Web 应用程序相关的示例已被替换。

  • 错误修正:模板更新延迟时间过去后(默认为 5 秒),即使模板文件未更改,也从模板缓存中删除了加载了URLTemplateLoader个子类的模板。如果您有许多模板,或者模板更新延迟设置为 0 秒,这可能会为高流量服务器带来很多额外负载。

  • 错误修正:即使正在使用调试TemplateException处理程序,FreeMarkerServlet也会抛出ServletException(因此您可能会看到 Error 500 页面而不是调试信息)。