库的创建:
当运行FTL模板时,会使用macro和assign指令创建变量的集合,这些变量的集合就称之为namespace(命名空间)。
在简单的情况下,可以只使用一个命名空间,称之为main namaspce(主命名空间)。
如果想要创建可以重复使用的宏,函数和其它变量的集合,就称之为library库。
首先在对应的工程目录下新建一个template文件夹,用于存放rj格式文件,新建一个index.rj和copyright.rj。
那么如果我想在index.rj中使用copyright.rj这个模板,可以使用import这个指令,它不仅仅要创建命名空间,且要通过import的调用者创建一个哈希变量(如index.rj中的me)。
这个时候我就可以通过me.变量的方式访问copyright.rj中的变量值,且要是index.rj中本身也存在一个名为mail的变量,可以直接使用${mail}访问,而与${my.mail}不会发生任何冲突。
index.rj:
<#compress>
<#import "/copyright.rj" as me>
<@me.copyright date="2013-2015"/>
${me.mail}
</#compress>
import中的rj文件路径是相对路径。
compress能够处理掉输出结果的前后空白,它是基于生成的输出内容,而不是模板。与剥离留白相反。
copyright.rj:
<#macro copyright date>
<p>Copyright (C) ${date} xuzengqiang. All rights reserved.</p>
</#macro>
<#assign mail="253948113@qq.com">
新建java代码:
package com.xuzengqiang.freemarker;
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
@SuppressWarnings("all")
public class FreemarkerTest2
{
public static void initData()
{
try
{
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File("template"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
Template temp=cfg.getTemplate("copyright.rj");
Writer writer=new OutputStreamWriter(System.out);
temp.process(null, writer);
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
initData();
}
}
这个时候就会在控制台打印输出:
<p>Copyright (C) 2013-2015 xuzengqiang. All rights reserved.</p>
253948113@qq.com
方法的编写,重写TemplateMethodModelEx接口中的
public TemplateModel exec(List list) throws TemplateModelException
1、返回的是一个TemplateModel类型,在freemarker内部,模板中所有可以用的变量都实现了TemplateModel。
在自己的数据类型中可以使用基本的java集合类作为变量,因为这些变量会在内部被替换成适当的TemplateModel类型,称之为object wrapping对象包装。
对象包装功能可以透明的将任何类型的对象转换成实现了TemplateModel接口类型的实例。如我们可以将ResulteSet转换成序列变量。
TemplateModel类型,除string对应的是SimpleScalar之外,其它的都是Simple+类型,如整数:SimpleNumber,序列SimpleSequence等。
2、参数list,表示的是参数列表,如${repeat("str",3)},那么repeat这个方法的参数都存在list这个参数列表中。
repeat.rj
<#assign str="love">
${repeat(str,3)}
RepeatMethod方法
package com.xuzengqiang.freemarker.framework;
import java.util.List;
import org.omg.CORBA.INTF_REPOS;
import freemarker.template.SimpleNumber;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
@SuppressWarnings("all")
public class RepeatMethod implements TemplateMethodModelEx
{
@Override
public TemplateModel exec(List list) throws TemplateModelException
{
String str=list.get(0).toString();
int num=Integer.valueOf(list.get(1).toString());
StringBuffer result=new StringBuffer();
for(int i=0;i<num;i++)
{
result.append(str);
}
return new SimpleScalar(result.toString());
}
}
主类:
package com.xuzengqiang.freemarker;
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import com.xuzengqiang.freemarker.framework.RepeatMethod;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
@SuppressWarnings("all")
public class RepeatMethodTest
{
public static void initData()
{
try
{
Configuration cfg = new Configuration();
cfg.clearTemplateCache(); //手动清除缓存
//加载模板
cfg.setDirectoryForTemplateLoading(new File("template"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
Template temp=cfg.getTemplate("repeat.rj");
Map root=new HashMap();
root.put("repeat", new RepeatMethod());
Writer writer=new OutputStreamWriter(System.out); //直接在控制台输出
temp.process(root, writer);
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
initData();
}
}
可以看到将一个实例放入到根数据模型中.
root.put("repeat", new RepeatMethod());
这时候你就可以扩展自己的方法了.在控制台打印的就是:
lovelovelove