freemarker編寫自定義標籤
阿新 • • 發佈:2019-02-11
freemarker提供了TemplateDirectiveModel介面,我們可以利用它來實現自定義標籤的編寫。
例子來源於freemarker中文參考手冊
如有:repeatDirective.rj
其中repeat指重複輸出,count指次數,cnt指變數,輸出最終結果是:<#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>
Test 1
Test 2
Test 3
Test 4
Test
<hr> Test
<hr> Test
1. Test
2. Test
3. Test
定義一個RepeatDirective類,是實現TemplateDirectiveModel介面,重寫其中的execute方法。
其中params是指引數,是以Map<String,TemplateModel>結構儲存的,如上面中的<@repeat count=3; cnt>其中count=3就以鍵值對的形式存在map中,只是3不是java型別,而是TemplateModel型別(整數:TemplateNumberModel,字串:TemplateScalarModel等),所以利用map.getValue(......)返回的是一個TemplateModel型別的資料,需轉換成int型別資料。public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException
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();
}
}