freemarker编写自定义标签

freemarker提供了TemplateDirectiveModel接口,我们可以利用它来实现自定义标签的编写。

例子来源于freemarker中文参考手册

如有:repeatDirective.rj

<#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>
其中repeat指重复输出,count指次数,cnt指变量,输出最终结果是:

Test 1
Test 2
Test 3
Test 4
Test
<hr> Test
<hr> Test
1. Test
2. Test
3. Test

定义一个RepeatDirective类,是实现TemplateDirectiveModel接口,重写其中的execute方法。

public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException,
			IOException
其中params是指参数,是以Map<String,TemplateModel>结构存储的,如上面中的<@repeat count=3; cnt>其中count=3就以键值对的形式存在map中,只是3不是java类型,而是TemplateModel类型(整数:TemplateNumberModel,字符串:TemplateScalarModel等),所以利用map.getValue(......)返回的是一个TemplateModel类型的数据,需转换成int类型数据。

loopVars:变量,如cnt,loopVars是一个TemplateModel类型的数组,我们可以在程序中给它赋值。

具体操作如下:

RepeatDirective

package com.xuzengqiang.freemarker.customDirective;

import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateNumberModel;
import freemarker.template.TemplateScalarModel;

/*
 * <@repeat>
 * ...
 * <@repeat>
 */
@SuppressWarnings("all")
public class RepeatDirective implements TemplateDirectiveModel
{
	private static final String COUNT="count";
	private static final String HR="hr";
	
	@Override
	public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException
	{	
		if(body==null)
		{
			throw new TemplateModelException("null body");
		}
		else 
		{
			int count=0;
			boolean hr=false;
			Iterator iterator=params.entrySet().iterator();
			while(iterator.hasNext())
			{
				Map.Entry<String,TemplateModel> param=(Map.Entry<String, TemplateModel>)iterator.next();
				String paramName=param.getKey();
				TemplateModel paramValue=param.getValue();
				if(paramName.equals(COUNT))
				{
					count=getInt(paramName,paramValue);
					if(count<0)
					{
						throw new TemplateModelException("次数不能小于0");
					}
				}
				if(paramName.equals(HR))
				{
					hr=getBoolean(paramName,paramValue);
				}
			}
			
			Writer out=env.getOut();
			for(int i=0;i<count;i++)
			{
				if(hr && i!=0)
				{
					out.write("<hr>");
				}
				//设置了循环变量
				if(loopVars.length>0)
				{
					loopVars[0]=new SimpleNumber(i+1);
				}
				body.render(out);                       
			}
		}
	}

	public static int getInt(String paramName,TemplateModel paramValue) throws TemplateModelException
	{
		if(paramValue==null)
		{
			return 0;
		}
		else 
		{
			if(paramValue instanceof TemplateScalarModel)  //是字符串
			{
				String value=((TemplateScalarModel)paramValue).getAsString();
				return Integer.valueOf(value);
			}
			else if(paramValue instanceof TemplateNumberModel)  //数字 
			{
				return ((TemplateNumberModel)paramValue).getAsNumber().intValue();
			}
			else 
			{
				throw new TemplateModelException("int转换异常!");
			}
		}
	}
	
	public static boolean getBoolean(String paramName,TemplateModel paramValue) throws TemplateModelException
	{
		if(paramValue==null)
		{
			return false;
		}
		else 
		{
			if(paramValue instanceof TemplateScalarModel)  //是字符串
			{
				String value=((TemplateScalarModel)paramValue).getAsString();
				return Boolean.valueOf(value);
			}
			else if(paramValue instanceof TemplateBooleanModel)  //boolean 
			{
				return ((TemplateBooleanModel)paramValue).getAsBoolean();
			}
			else 
			{
				throw new TemplateModelException("boolean转换异常!");
			}
		}
	}
	
}
主类:

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.customDirective.RepeatDirective;
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("repeatDirective.rj");
			
			Map root=new HashMap();
			root.put("repeat", new RepeatDirective());
			Writer writer=new OutputStreamWriter(System.out); //直接在控制台输出
			temp.process(root, writer);
			writer.flush();
			
		} 
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args)
	{
		initData();
	}
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值