FreeMarker 2.3.11版本以后提供了新的自定义标签接口TemplateDirectiveModel 以替代TemplateTransformModel,

下面是一个转换自定义标签的内容体中字母为大写字母的例子:

 1 import java.io.IOException;
 2 import java.io.Writer;
 3 import java.util.Map;
 4 
 5 import freemarker.core.Environment;
 6 import freemarker.template.TemplateDirectiveBody;
 7 import freemarker.template.TemplateDirectiveModel;
 8 import freemarker.template.TemplateException;
 9 import freemarker.template.TemplateModel;
10 import freemarker.template.TemplateModelException;
11 
12 /**
13  * FreeMarker 自定义指令,用于转换指令内容体中的字母为大写字母。
14  * 
15  */
16 public class UpperDirective implements TemplateDirectiveModel {
17 
18     public void execute(Environment env, Map params, TemplateModel[] loopVars,
19             TemplateDirectiveBody body) throws TemplateException, IOException {
20         // 检查是否传递参数,此指令禁止传参!
21         if (!params.isEmpty()) {
22             throw new TemplateModelException(
23                     "This directive doesn't allow parameters.");
24         }
25         // 禁用循环变量
26         /*
27          * 循环变量
28                  用户定义指令可以有循环变量,通常用于重复嵌套内容,基本用法是:作为nested指令的参数传递循环变量的实际值,而在调用用户定义指令时,在${"<@…>"}开始标记的参数后面指定循环变量的名字
29                  例子:
30             <#macro repeat count>
31               <#list 1..count as x>
32                 <#nested x, x/2, x==count>
33               </#list>
34             </#macro>
35             <@repeat count=4 ; c, halfc, last>
36               ${c}. ${halfc}<#if last> Last!</#if>
37             </@repeat> 
38         */
39         if (loopVars.length != 0) {
40             throw new TemplateModelException(
41                     "This directive doesn't allow loop variables.");
42         }
43 
44         // 指令内容体不为空
45         if (body != null) {
46             // Executes the nested body. Same as <#nested> in FTL, except
47             // that we use our own writer instead of the current output writer.
48             body.render(new UpperCaseFilterWriter(env.getOut()));
49         } else {
50             throw new RuntimeException("missing body");
51         }
52     }
53 
54     /**
55      * 输出流的包装器(转换大写字母)
56      */
57     private static class UpperCaseFilterWriter extends Writer {
58 
59         private final Writer out;
60 
61         UpperCaseFilterWriter(Writer out) {
62             this.out = out;
63         }
64 
65         public void write(char[] cbuf, int off, int len) throws IOException {
66             char[] transformedCbuf = new char[len];
67             for (int i = 0; i < len; i++) {
68                 transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);
69             }
70             out.write(transformedCbuf);
71         }
72 
73         public void flush() throws IOException {
74             out.flush();
75         }
76 
77         public void close() throws IOException {
78             out.close();
79         }
80     }
81 
82 }
 1 import java.io.File;
 2 import java.io.IOException;
 3 import java.io.Writer;
 4 import java.util.Map;
 5 
 6 import freemarker.template.Configuration;
 7 import freemarker.template.DefaultObjectWrapper;
 8 import freemarker.template.Template;
 9 import freemarker.template.TemplateException;
10 
11 /**
12  * 
13  * 模板工具类
14  */
15 public class FreeMarkertUtil {
16     /**
17      * @param templatePath 模板文件存放目录 
18      * @param templateName 模板文件名称 
19      * @param root 数据模型根对象
20      * @param templateEncoding 模板文件的编码方式
21      * @param out 输出流
22      */
23     public static void processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){
24         try {
25             Configuration config=new Configuration();
26             File file=new File(templatePath);
27             //设置要解析的模板所在的目录,并加载模板文件
28             config.setDirectoryForTemplateLoading(file);
29             //设置包装器,并将对象包装为数据模型
30             config.setObjectWrapper(new DefaultObjectWrapper());
31             
32             //获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致
33             Template template=config.getTemplate(templateName,templateEncoding);
34             //合并数据模型与模板
35             
36             template.process(root, out);
37             out.flush();
38             out.close();
39         } catch (IOException e) {
40             e.printStackTrace();
41         }catch (TemplateException e) {
42             e.printStackTrace();
43         }
44         
45     } 
46 }
 1 import java.io.OutputStreamWriter;
 2 import java.util.HashMap;
 3 import java.util.Map;
 4 
 5 /**
 6  * 
 7  * 客户端测试模板输入类
 8  */
 9 public class ClientTest {
10     public static void main(String[] args) {
11         Map<String,Object> root=new HashMap<String, Object>();
12 
13         root.put("upper", new UpperDirective());
14         
15         FreeMarkertUtil.processTemplate("src/templates","demo01.ftl", "UTF-8", root, new OutputStreamWriter(System.out));
16         
17     }
18 }

 模板文件demo01.ftl如下:

1 <@upper>
2   bar
3   <#-- All kind of FTL is allowed here -->
4   <#list ["red", "green", "blue"] as color>
5     ${color}
6   </#list>
7   baaz
8 </@upper>

 

posted on 2015-02-05 15:42  kotori  阅读(385)  评论(0编辑  收藏  举报