FreeMarker <#include> 指令扩展
2016-08-27 14:32
316 查看
什么是 FreeMarker
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本( HTML 网页,电子邮件,配置文件,源代码等)的通用工具。它不是面向最终用户的,而是一个 Java 类库,是一款程序员可以嵌入他们所开发产品的组件。简单说,FreeMarker: 模板 + 数据 = 输出
FreeMarker 内建指令 —— include
FreeMarker 中包含很多内建的指令,犹如 JSP 中的标签一样。这里主要讲下include指令。参考 Freemarker 官方文档,其语法格式如下:
<#include path> 或 <#include path options>
其中:
path: 要包含文件的路径;一个算作是字符串的表达式。(用其他话说, 它不用是一个固定的字符串,它也可以是像 profile.baseDir + "/menu.ftl" 这样的东西。)
options: 一个或多个这样的选项: encoding=encoding, parse=parse
encoding: 算作是字符串的表达式
parse: 算作是布尔值的表达式(为了向下兼容,也接受一部分字符串值)
ignore_missing: 算作是布尔值的表达式
你可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由
path参数指定)。 被包含模板的输出格式是在
include标签出现的位置插入的。被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。值得注意的是,
include指令不能由被包含文件的内容所替代,它只是当 FreeMarker 每次在模板处理期间到达 include 指令时处理被包含的文件。也就是说,这边可以在执行时,动态指定需包含的 FreeMarker 模板文件。
一个错误场景
假设有这样一个场景,需要介绍全国的每一个省。每个省有一个对应的以省份名称命名的 FreeMarker 模板(当然,这些模板都是在一个总的模板下显示),如:js.ftl。一般来说,我们可以这样写总的模板,来达到动态包含省份的模板。
<!DOCTYPE html> <html> <head> ... </head> <body> <#include "/${province}.ftl"/> </body> </html>
看着上面的代码,是不是觉得 FreeMarker 还是很方便很强大的啊!但是坑来了,假设目前项目还没有开发完成,也就是说,有的省份还没有对应的 FreeMarker 模板,那么会出现什么情况呢?直接报错了。对于项目没做完这种事,我们得找个临时方案啊,给那些没有开发模板的省份来个默认页面,那么用
include指令貌似有点力不从心。如何解决呢?FreeMarker 有自定义指令的功能,那就定义一个加强版的
include指令吧,使得该指令在找不到指定模板的情况下,包含一个默认的模板。
public class IncludeXMacro implements TemplateDirectiveModel { private static final String PATH_PARAM = "template"; private static final String DEFALUT_PATH_PARAM = "default_template"; @Override public void execute(Environment environment, @SuppressWarnings("rawtypes") Map params, TemplateModel[] templateModel, TemplateDirectiveBody directiveBody) throws TemplateException, IOException { TemplateLoader templateLoader = environment.getConfiguration().getTemplateLoader(); String fullTemplatePath = getFullTemplatePath(environment, params, PATH_PARAM); if (templateLoader.findTemplateSource(fullTemplatePath) != null) { environment.include(environment.getTemplateForInclusion(fullTemplatePath, null, true)); } else { String defaultFullTemplatePath = getFullTemplatePath(environment, params, DEFALUT_PATH_PARAM); if (templateLoader.findTemplateSource(defaultFullTemplatePath) == null) { throw new _MiscTemplateException(environment, "Missing template file path:" + defaultFullTemplatePath); } environment.include(environment.getTemplateForInclusion(defaultFullTemplatePath, null, true)); } } /** * Description:获取ftl完整路径 <br> */ private String getFullTemplatePath(Environment environment, @SuppressWarnings("rawtypes") Map params, String templatePath) throws MalformedTemplateNameException { if (!params.containsKey(templatePath)) { throw new MalformedTemplateNameException("missing required parameter '" + templatePath, "'"); } String currentTemplateName = environment.getTemplate().getName(); final String baseName = FilenameUtils.getPath(currentTemplateName); final String targetName = params.get(templatePath).toString(); final String fullTemplatePath = environment.toFullTemplateName(baseName, targetName); return fullTemplatePath; } }
FreeMarker 在这边就不详细讲了,官网讲的很清楚。我们给这个自定义的指令起个名字:
includeX,然后就可以这样使用了:
<@includeX template="/${province}.ftl" default_template="/default.ftl"/>
相关文章推荐
- jsp动作元素<jsp:include page="">与指令元素<%include file=""%>的区别
- include指令和include动作以及<c:import>总结
- jsp用静态指令<%=include file=""%>编码问题
- <%@include...> 与<jsp:include....>指令的区别
- <%@include...> 与<jsp:include....>指令的区别
- Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用
- Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用
- JSP的基本语法之include指令与<jsp:include>动作标识的区别
- include指令和include动作以及<c:import>问题
- <jsp:include>标签与include指令的比较
- <jsp:include>标签 和 include 指令的比较
- <#include> vs <#import> in FreeMarker
- JSP_include指令和<jsp:include>
- JSP基本语法--包含指令<%@include file="路径"%> <jsp:include page>
- 面向对象系统分析与设计专题<7>__UML用例图之泛化(generalization)、扩展(extend)和包含(include)关系
- <jsp:include>与include指令的区别
- Include指令和<jsp:include>两种动作表示的区别
- FreeMarker编写一个用于实现<select/>效果的通用指令
- include指令与<jsp:include>动作的区别
- JSP_include指令和<jsp:include>