freemarker中实现自定义标签(2.3.11版本以后的方式)

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>

 

你可能感兴趣的:(freemarker)