FreeMarker概述
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写
FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图)
FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件
FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非
Web应用程序环境
FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP
标记库
FreeMarker是免费的
FreeMarker特性 1、通用目标
能够生成各种文本:HTML、XML、RTF、Java源代码等等 易于嵌入到你的产品中:轻量级;不需要Servlet环境
插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等
你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器
2、强大的模板语言
所有常用的指令:include、if/elseif/else、循环结构 在模板中创建和改变变量
几乎在任何地方都可以使用复杂表达式来指定值 命名的宏,可以具有位置参数和嵌套内容 名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突
输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;你可以定义自己的转换
3、通用数据模型
FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示
你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰
4、为Web准备
在模板语言中内建处理典型Web相关任务(如HTML转义)的结构 能够集成到Model2 Web应用框架中作为JSP的替代 支持JSP标记库
为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员
5、智能的国际化和本地化
字符集智能化(内部使用UNICODE) 数字格式本地化敏感
日期和时间格式本地化敏感
非US字符集可以用作标识(如变量名) 多种不同语言的相同模板
6、强大的XML处理能力
<#recurse> 和<#visit>指令(2.3版本)用于递归遍历XML树 在模板中清楚和直觉的访问XML对象模型
FreeMarker vs. Velocity 1、概述
Velocity是一个简单而且更加轻量级的工具,但是它没有达到FreeMarker能够做的许多任务,而且它的模板语言不是很强大
我们认为对于大多数应用程序,FreeMarker比Velocity工作更简单,因为: ?使用Velocity,你需要寻找特定工具或各种工作环境来一次次的解决典型的模板创作任务,结果会浪费更多时间
?工作环境经常意味着在Velocity模板中直接使用Java对象的方法,这违反了简单、无编程HTML设计的观念
?或者将表示任务移到控制器代码中,这违反了MVC模式
使用FreeMarker,可以以out-of-the-box(如何翻译确切?)的方式实现Velocity所能做的
2、特性比较清单
下面是一个使用FreeMarker能够实现,而Velocity不能实现的不太全面的特性清单: (1)数字和日期支持
可以对任何数字类型进行算术运算和比较,包括精度类型 可以比较和显示(格式化)日期/时间值 (2)国际化
根据各种内建和定制的数字格式,格式化本地敏感的数字
根据各种内建和定制的日期格式,格式化本地敏感和时区敏感的日期
标识(变量名)可以包含非英语字符,如重音字符、阿拉伯字符、中文字符等 (3)循环处理
可以跳出循环
可以在循环外访问循环体内的控制变量 可以测试是否达到最后一次循环 (4)模板级别的数组处理
可以使用类似[i]语法的索引方式访问数组元素 可以查询数组长度 (5)宏
宏可以有局部变量
可以递归调用宏,同样可以在模板的后面定义要调用的宏 调用宏时,可以按位置或名字的方式传递参数
宏参数可以有缺省值,使得在调用时忽略参数也有效
调用的宏可以有嵌套的体内容(<@myMacro>body@myMacro>),能够在宏被调用时进行处理
宏是纯变量的,可以基于表达式来执行宏,或者作为参数传递给另一个宏 (6)命名空间
可以对变量使用多命名空间,这对创建宏库很重要,因为这可以避免应用程序中指定的变量和宏库中变量的名字冲突
(7)使用内建的函数/操作符维护Java无关的string、list和map
可以将字符串转换成大/小写、首字符大/小写,对HTML、XML或RTF进行转义处理,substring、split、查询字符串长度、find/replace子串等等
通过索引访问list元素,获得子list,合并list,查询list长度,对list排序 通过key变量访问map元素,检查map是否为空,获得key或值的list (8)揭示模板中的错误
当访问一个未定义的变量,FreeMarker不会沉默;你可以配置FreeMarker来停止render模板显示错误信息,或者跳过错误部分;无论哪种,FreeMarker会记录问题(日志)
在写错指令名时,FreeMarker会抛出异常 (9)高级render控制
可以使用一组标记来封装模板的一块区域,以便在块区中所有要修改的地方应用HTML或XML转义(或其它使用FreeMarker表达式表示的转换)
FreeMarker有转换器,它们是模板的一块区域,在render时,通过转换过滤;内建的转换器包括空白字符压缩、HTML和XML转义;你可以实现自己的转换器;当然转换器可以嵌套
可以使用flush指令显式的flush输出 可以使用stop指令停止render (10)文字
除了通常的字符串、数字和布尔值文字,也可以在模板中定义list和map文字 支持所有的Java转义文字:\\b、\\t、\\n、\\f、\\r、\\”、\\’、\\\\,也支持\\xXXXX使用UNICODE指定字符
(11)高级空白字符移除
FreeMarker坚持移除各行只包含不输出FreeMarker标记的空白字符 对于明显要整修掉不需要的空白字符的指令来说,空白字符是个大问题
(12)集成其它技术
可以在模板中使用JSP标记库 可以直接在Python工程中使用 (13)强大的XML转换能力
在2.3版本中,FreeMarker具有强大的新XML转换能力,使得替代XSLT成为可能 Velocity在这方面是无法真正竞争的,除非改进核心引擎,如支持宏库映射到名字空间,宏中支持局部变量
(14)高级模板元程序
可以捕获输出的任何部分到context变量中
可以解释任何context变量,如果它是一个模板定义 上述两者的结合使用
FreeMarker设计指南(1)
1、快速入门
(1)模板 + 数据模型 = 输出
? FreeMarker基于设计者和程序员是具有不同专业技能的不同个体的观念 ? 他们是分工劳动的:设计者专注于表示——创建HTML文件、图片、Web页
面的其它可视化方面;程序员创建系统,生成设计页面要显示的数据 ? 经常会遇到的问题是:在Web页面(或其它类型的文档)中显示的信息在
设计页面时是无效的,是基于动态数据的
? 在这里,你可以在HTML(或其它要输出的文本)中加入一些特定指令,
FreeMarker会在输出页面给最终用户时,用适当的数据替代这些代码 ? 下面是一个例子:
Welcome ${user}!
Our latest product:
!
? 这个例子是在简单的HTML中加入了一些由${?}包围的特定代码,这些特
定代码是FreeMarker的指令,而包含FreeMarker的指令的文件就称为模板(Template)
? 至于user、latestProduct.url和latestProduct.name来自于数据模型
(data model)
? 数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于
数据库、文件,甚至于在程序中直接生成
? 模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型 ? 下面是一个可能的数据模型:
(root) |
+- user = \ |
+- latestProduct |
+- url = \ |
+- name = \
? 数据模型类似于计算机的文件系统,latestProduct可以看作是目录,而
user、url和name看作是文件,url和name文件位于latestProduct目录中(这只是一个比喻,实际并不存在)
? 当FreeMarker将上面的数据模型合并到模板中,就创建了下面的输出:
Welcome Big Joe!
Our latest product:
!
(2)数据模型
? 典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子:
(root) | +- animals | |