2.2
Page Contents
发布日期:2003-03-27
此版本引入了一些非常重要的新功能。不幸的是,进化又一次痛苦。我们有一些非向后兼容的更改(请参见下文)。另外,对于那些正在 await 所需的本机日期/时间类型的人,对不起,它仍然不在这里(由于团队内部出现一些混乱,请耐心 await,即将到来)。
非向后兼容的更改!
-
宏现在是普通变量。这意味着如果您很不幸,并且您同时具有一个宏和另一个具有相同名称的变量,那么该变量将覆盖该宏,因此您的旧模板将发生故障。如果您有一组公共宏,则应使用新的namespace feature来防止与模板中使用的变量发生意外冲突。
-
随着新的namespace support的引入,
global
和assign
指令不再是同义词。assign
在当前namespace
中创建一个变量,而global
创建在所有命名空间中可见的变量(就像该变量将在数据模型中一样)。因此,使用assign
创建的变量更具体,并且隐藏使用global
创建的同名变量。结果,如果您在模板中的同一变量中同时使用了global
和assign
,则它们将出现故障。解决方案是用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指令在每个模板的基础上启用/禁用它。 -
引入了一些新的指令:
nested
,import
,escape
,noescape
,t
,rt
,lt
。这意味着,如果您很不幸,并且模板的文本中包含类似<nested>
的内容,那么它将被误解为指令。为了将来避免这种问题,我们建议大家从旧语法切换到新语法(“严格语法”)。无论如何,严格语法将是从某些更高版本开始的默认语法。我们计划发布一种转换工具,用于转换旧模板。有关更多信息,请阅读:模板语言参考/不建议使用的 FTL 构造/旧的 FTL 语法 -
FreemarkerServlet
创建的数据模型现在使用自动作用域发现,因此不再必须写入Application.attrName
,Session.attrName
,Request.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-ins:
index_of
,last_index_of
,starts_with
,ends_with
,replace
,split
,chop_linebreak
,uncap_first
。 -
新的sequence built-ins:
sort
,sort_by
。 -
新的内置函数供 maven 检查变量的类型。看到:is_... built-ins
-
新的内置函数供 maven 创建某些 Java
TemplateModel
实现的变量。看到:new built-in -
新的内置namespace,用于获取宏的名称空间。
-
新的表达式类型:特殊变量表达式。为了防止在向后兼容时引入新的 sched 义变量,现在使用特殊变量表达式来访问它们。
-
新指令:
t
,rt
和lt
指令使您可以在极端 FTL 应用程序中进行显式空格删除。有关更多信息,请阅读the reference。 -
现在,
assign
,local
和global
可以捕获将嵌套模板片段生成的输出生成到变量中。这不赞成capture_output
转换。更多信息:分配指令参考 -
批量分配(如
<#assign x=1, y=2, z=3>
)不再需要冒号来分隔分配(如<#assign x=1 y=2 z=3>
),尽管仍然允许保留向后兼容性。 -
包含
//:
的路径被视为绝对路径。 -
include
和transform
指令不再需要使用分号从参数列表中分离模板或转换名称,尽管仍然可以保留其向后兼容性。 -
#
-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.String
和Character
对象。这样,通过BeansWrapper
包裹的数字对象将受到 FreeMarker 的数字格式化机制的约束。副作用是,以前在相等和不相等运算中接受的非字符串和非数字对象(因为它们具有字符串表示形式)现在将导致引擎在尝试比较时引发异常。-
java.lang.Character
对象通过BeansWrapper
作为标量公开。 -
实验性功能:使用
BeansWrapper
的setSimpleMapWrapper
方法,可以将其配置为将java.util.Map
-s 包装为TemplateHashModelEx
-s,并且不公开对象的方法。
-
-
TransformControl
接口(之前是实验性的):如果TemplateTransformModel.getWriter
返回的Writer
实现了此接口,则它可以指示引擎跳过或重复对嵌套内容的评估,并获得有关嵌套内容评估期间引发的异常的通知。请注意,现在允许onStart
和afterBody
方法抛出IOException
。有关更多信息,请阅读 API 文档。 -
可以使用新的
Configuration
方法禁用本地化查找:set/getLocalizedLookup
,clearTemplateCache
-
新界面
freemarker.cache.CacheStorage
允许用户使用cache_storage
设置插入自定义模板缓存策略。现在,核心软件包附带了两种实现:SoftCacheStorage
和StrongCacheStorage
。有关更多信息,请阅读:程序员指南/配置/模板加载 -
您可以使用
Configurable
个超类的新setSetting(String key, String value)
方法(如Configuration
)来设置字符串名称和字符串值的设置。您也可以使用setSettings
方法从.properties
文件中加载设置。 -
其他新的
Configuration
方法:clearTemplateCache
,clearSharedVariables
,getTemplateLoader
和clone
。 -
更改为
TemplateTransformModel
界面:getWriter
可以抛出IOException
,如果转换不支持主体内容,则可以返回null
。 -
到目前为止,如果在不使用参数的情况下调用
TemplateTransformModel.getWriter
,则将其作为参数 Map 接收到空值。从现在开始,它将收到一个空的 Map。请注意,以前的 API 文档没有说明如果没有参数,则它总是会收到 null,因此,绝望的只有极少数的类会利用此设计错误。 -
FreemarkerServlet
的各种改进: -
数据模型现在使用自动作用域发现,因此不再必须编写
Application.attrName
,Session.attrName
,Request.attrName
;写attrName
就足够了。有关更多信息read this。-
FreemarkerServlet
现在将模板文件的编码用于输出,除非您在ContentType
init-param 中指定了编码,例如text/html; charset=UTF-8
。 -
可以通过 Servlet 初始化参数(
template_exception_handler
,locale
,number_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
设置插入自定义模板缓存策略。现在,核心软件包附带了两种实现:SoftCacheStorage
和StrongCacheStorage
。有关更多信息,请阅读:程序员指南/配置/模板加载 -
您可以使用
Configurable
个超类的新setSetting(String key, String value)
方法(如Configuration
)来设置字符串名称和字符串值的设置。 -
其他新的
Configuration
方法:getTemplateLoader
,clone
。 -
现在,
assign
,local
和global
可以捕获将嵌套模板片段生成的输出生成到变量中。这不赞成capture_output
转换。更多信息:分配指令参考 -
其他新的
Configuration
方法:getTemplateLoader
,clone
。 -
更改为
TemplateTransformModel
界面:getWriter
可以抛出IOException
,如果转换不支持主体内容,则可以返回null
。 -
到目前为止,如果在不使用参数的情况下调用
TemplateTransformModel.getWriter
,则将其作为参数 Map 接收到空值。从现在开始,它将收到一个空的 Map。请注意,以前的 API 文档没有说明如果没有参数,则它总是会收到 null,因此,绝望的只有极少数的类会利用此设计错误。 -
更改为
TemplateControl
接口:现在允许onStart
和afterBody
方法抛出IOException
。 -
包含
//:
的路径被视为绝对路径。 -
新的string built-ins:
index_of
,last_index_of
,starts_with
,ends_with
,replace
,split
,chop_linebreak
。 -
新的sequence built-ins:
sort
,sort_by
。 -
可以通过 Servlet 初始化参数(
template_exception_handler
,locale
,number_format
等)设置所有Configuration
级别的设置。 -
错误修正:如果类仅在
WEB-INF
中可用,则可能找不到类,并且 FreeMarker 尝试动态加载该类。 -
错误修正:调用
setTemplateLoader
时,Configuration
的setLocalizedLookup(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.TemplateLoader
的normalizeName
方法已删除,因为它引起了太多麻烦。相反,规范化发生在TempateCache
中的单个点上。因此,FreeMarker 现在对模板路径的格式更加严格,因为/../
之类的内容由内核解释。 -
实验性功能:使用
BeansWrapper
的setSimpleMapWrapper
方法,可以将其配置为将java.util.Map
-s 包装为TemplateHashModelEx
-s,并且不公开对象的方法。 -
新的
Configuration
方法:set/getLocalizedLookup
,clearTemplateCache
,clearSharedVariables
。 -
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。
-
新指令:
t
,rt
和lt
指令使您可以在极端 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 页面而不是调试信息)。