freemarker中实现自定义标签
private static final String PARAM_NAME_COUNT = "count";private static final String PARAM_NAME_HR = "hr";
public void execute(Environment env, Map params, TemplateModel[] loopVars,TemplateDirectiveBody body) throws TemplateException, IOException {
// ---------------------------------// 处理参数
int countParam = 0;boolean countParamSet = false;boolean hrParam = false;
Iterator?paramIter = params.entrySet().iterator();while (paramIter.hasNext()) {Map.Entry ent = (Map.Entry) paramIter.next();
String paramName = (String) ent.getKey();TemplateModel paramValue = (TemplateModel) ent.getValue();
if (paramName.equals(PARAM_NAME_COUNT)) {if (!(paramValue instanceof TemplateNumberModel)) {throw new TemplateModelException("The "" + PARAM_NAME_HR+ "" parameter " + "must be a number.");}countParam = ((TemplateNumberModel) paramValue).getAsNumber().intValue();countParamSet = true;if (countParam < 0) {throw new TemplateModelException("The "" + PARAM_NAME_HR+ "" parameter " + "can't be negative.");}} else if (paramName.equals(PARAM_NAME_HR)) {if (!(paramValue instanceof TemplateBooleanModel)) {throw new TemplateModelException("The "" + PARAM_NAME_HR+ "" parameter " + "must be a boolean.");}hrParam = ((TemplateBooleanModel) paramValue).getAsBoolean();} else {throw new TemplateModelException("Unsupported parameter: "+ paramName);}}if (!countParamSet) {throw new TemplateModelException("The required ""+ PARAM_NAME_COUNT + "" paramter" + "is missing.");}
if (loopVars.length > 1) {throw new TemplateModelException("At most one loop variable is allowed.");}
// Yeah, it was long and boring...
// ---------------------------------// 真正开始处理输出内容
Writer out = env.getOut();if (body != null) {for?(int i = 0; i < countParam; i++) {// 输出??<hr> 如果 参数hr 设置为trueif (hrParam && i != 0) {out.write("<hr>");}
// 设置循环变量if (loopVars.length > 0) {loopVars[0] = new SimpleNumber(i + 1);}
// 执行标签内容(same as <#nested> in FTL). body.render(env.getOut());}}}
}
?
Java代码import java.io.File;import java.io.IOException;import java.io.Writer;import java.util.Map;?
import freemarker.template.Configuration;import freemarker.template.DefaultObjectWrapper;import freemarker.template.Template;import freemarker.template.TemplateException;
/** * * 模板工具类 */public class FreeMarkertUtil {/** * @param templatePath 模板文件存放目录 * @param templateName 模板文件名称 * @param root 数据模型根对象 * @param templateEncoding 模板文件的编码方式 * @param out 输出流 */public static void processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){try {Configuration config=new Configuration();File file=new File(templatePath);//设置要解析的模板所在的目录,并加载模板文件config.setDirectoryForTemplateLoading(file);//设置包装器,并将对象包装为数据模型config.setObjectWrapper(new DefaultObjectWrapper());
//获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致Template template=config.getTemplate(templateName,templateEncoding);//合并数据模型与模板
????template.process(root, out);????out.flush();????out.close();} catch (IOException e) {e.printStackTrace();}catch (TemplateException e) {e.printStackTrace();}
} }
?
?
Java代码import java.io.OutputStreamWriter;import java.util.HashMap;import java.util.Map;?
/** * * 客户端测试模板输入类 */public class RepeatTest {public static void main(String[] args) {Map<String,Object> root=new HashMap<String, Object>();
root.put("repeat", new RepeatDirective());
FreeMarkertUtil.processTemplate("src/templates","repeat.ftl", "UTF-8", root, new OutputStreamWriter(System.out));
}}
?
?模板文件repeat.ftl如下:
?
Java代码<#assign x = 1>?
一个参数:<@repeat count=4>??Test ${x}??<#assign x = x + 1></@repeat>
二个参数:<@repeat count=3 hr=true>??Test</@repeat>
循环变量:<@repeat count=3; cnt>??${cnt}. Test</@repeat>??
?
?输出结果:
Java代码