1. 模板文件 test04.ftl

foo
<@customUpper>
bar f
<#-- 这里同意使用全部的 FTL -->
<#list ["red", "green", "blue"] as color>
${color}
</#list>
baaz
</@customUpper>
wombat

2. 自己定义指令类 UpperDirective.java

ps: 一个把字符串变为大写的指令

package com.freemarker.test04.Directives;

import java.io.IOException;
import java.io.Writer;
import java.util.Map; import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException; /**
* FreeMarker 的用户自己定义指令在逐步改变
* 它嵌套内容的输出转换为大写形式
* <p><b>指令内容</b></p>
* <p>指令參数:无
* <p>循环变量:无
* <p>指令嵌套内容:是
*/
public class UpperDirective implements TemplateDirectiveModel { public void execute(Environment env,
Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body)
throws TemplateException, IOException {
// 检查參数是否传入
if (!params.isEmpty()) {
throw new TemplateModelException(
"This directive doesn't allow parameters.");
}
if (loopVars.length != 0) {
throw new TemplateModelException(
"This directive doesn't allow loop variables.");
} // 是否有非空的嵌入内容
if (body != null) {
// 执行嵌入体部分,和 FTL 中的<#nested>一样,除了
// 我们使用我们自己的 writer 来取代当前的 output writer.
body.render(new UpperCaseFilterWriter(env.getOut()));
} else {
throw new RuntimeException("missing body");
}
} /**
* {@link Writer}改变字符流到大写形式,
* 并且把它发送到另外一个{@link Writer}中。 */
private static class UpperCaseFilterWriter extends Writer { private final Writer out; UpperCaseFilterWriter (Writer out) {
this.out = out;
} @Override
public void write(char[] cbuf, int off, int len)throws IOException {
char[] transformedCbuf = new char[len];
for (int i = 0; i < len; i++) {
transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);
}
out.write(transformedCbuf);
} public void flush() throws IOException {
out.flush();
} public void close() throws IOException {
out.close();
}
} }

3. 測试类文件 Test.java

package com.freemarker.test04.Directives;

import freemarker.template.*;
import java.util.*;
import java.io.*; public class Test { public static void main(String[] args) throws Exception { // 创建 Freemarker 配置实例
Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
// 指定模板文件从何处载入的数据源,这里设置成一个文件文件夹。 cfg.setDirectoryForTemplateLoading(new File("templates"));
cfg.setDefaultEncoding("UTF-8");
// 简单地又一次抛出异常; 这应该在大多数生产系统中使用。 cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); // 创建一个数据模型
Map root = new HashMap();
// 測试自己定义指令 --------------------------------
root.put("customUpper", new UpperDirective()); // 获取模板(使用内部缓存)
Template temp = cfg.getTemplate("test04.ftl"); // 合并数据模型模板
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
out.flush();
out.close();
// 注意: ------------
// 为了简单起见,这里压制了异常(在方法签名中声明了异常,译者注),而在正式执行的产品中不要这样做。 }
}

执行结果

foo
BAR F
RED
GREEN
BLUE
BAAZ
wombat

FreeMarker 自己定义指令(三)的更多相关文章

  1. freemarker 自己定义指令

    1 简单介绍 自己定义指令能够使用 macro 指令来定义,这是模板设计者所关心的内容. Java 程序猿若不想在模板中实 现定义指令 ,而是在 Java 语言中实现指令 的定义,这时 能够使用fre ...

  2. freemarker自己定义标签报错(三)

    freemarker自己定义标签 1.错误描写叙述 freemarker.core.ParseException: Encountered " " at line 14, colu ...

  3. AngularJS--自定义指令和模板

    一.自定义指令: 1. 先创建模块    var app=angular.module("myApp",[]); 2. 创建自定义指令 (directive后面的参数一:自定义指令 ...

  4. 你知道用AngularJs怎么定义指令吗?

    前言 最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方.   Angularjs指令定义的API AngularJs的指令定义大致如下 ang ...

  5. [转]你知道用AngularJs怎么定义指令吗?--很详细

    前言 最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方.   Angularjs指令定义的API AngularJs的指令定义大致如下 ang ...

  6. freemarker自己定义标签报错(七)

    1.错误描写叙述 六月 09, 2014 11:11:09 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Template pr ...

  7. freemarker自己定义标签(一)

    freemarker自己定义标签 1.自己定义标签说明 宏变量存储模板片段能够被用作自己定义指令macro 2.演示样例说明 <html> <head> <meta ht ...

  8. AngularJS---自定义指令

    AngularJS提供了一系列的内置指令,如ng开头的指令,同时AngularJS也允许用户自定义指令. 目录: 1.自定义指令 2.使用自定义指令 3.自定义指令的内嵌使用 自定义指令 Angula ...

  9. 工作流学习——Activiti流程定义管理三步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46602419 ***************************************** ...

随机推荐

  1. 浅谈Exchange 2013开发-如何操作邮件的附件

    因为项目中客户有一个的要求,所以这个Exchange前段时间搞的我很是头疼,没接触过这个东西,但是现在看来,纸老虎一个.希望我的经验可以帮助初次接触它的人少走一些弯路! 简单介绍一下:客户要求在自己的 ...

  2. Dictionary通过Value找到它的key

    private void GetDicKeyByValue() { Dictionary<string, string> dic = new Dictionary<string, s ...

  3. JAVA NIO 结合多线程

    NIO 的选择器采用了多路复用(Multiplexing)技术,可在一个选择器上处理多个套接字, 通过获取读写通道来进行 IO 操作.由于网络带宽等原因,在通道的读.写操作中是容易出现等待的, 所以在 ...

  4. React/React Native 的ES5 ES6写法对照表-b

    很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教 ...

  5. "Invalid bound statement (not found): com.sitech.admin.dao.TbOpenAbilityInfoDao.findAbilityReadyUp"mybatis配置文件bug

    问题描述: 通常在正常启动某项工程后操作某个功能时抛出的bug: org.apache.ibatis.binding.BindingException: Invalid bound statement ...

  6. JAVA抽象类和接口的深入探讨

    Java 语言中,抽象类(abstract class) 和接口(interface) 是抽象思想的两种体现形式.初学者很容易把这两者搞混,所以Java面试中考抽象类和接口的区别的面试题也常有出现的. ...

  7. Hashtable,HashMap实现原理

    http://blog.csdn.net/czh0766/article/details/5260360 昨天看了算法导论对散列表的介绍,今天看了一下Hashtable, HashMap这两个类的源代 ...

  8. PYTHON文本处理指南之日志LOG解析

    处理特定字段的内容,并指指定条件输出. 注意代码中用一个方法列表,并且将方法参数延后传递. GOOGLE作过PYTHON代码的水平,就是不一样呀. 希望能学到这种通用的技巧. 只是,英文PDF看起来有 ...

  9. 关于用xercesImpl包解析xml文件遇中文报错问题

    今天在运行项目时报错: Caused by: org.apache.xerces.impl.io.MalformedByteSequenceException: 3 字节 UTF-8 序列的字节 3 ...

  10. log4j学习日记-写入数据库

    1.首先创建日志数据库 用的是MySQL CREATE TABLE `td_log` (   `lid` int(11) NOT NULL AUTO_INCREMENT,   `lusername` ...