Freemarker自定義指令
阿新 • • 發佈:2019-02-12
場景
在做一個CMS網站時,要列出網站欄目,比如有新聞,科技,體育,財經等欄目。欄目內容存放在資料庫中。
呼叫語法
//沒有迴圈變數
<@user_def_dir_exp param1=val1 param2=val2 ... paramN=valN/>
//有迴圈變數
<@user_def_dir_exp param1=val1 param2=val2 ... paramN=valN ;lv1, lv2, ..., lvN/>
自定義指令使用
cms_chanel_list指令的作用是按傳入的引數count找出指定數量的欄目,並且過濾掉名字為“體育”的欄目。
<@cms_chanel_list count=5 exclude="體育">
<#list chllist as c>
<dt>
<a href="#" target="_self"><span>${c.name}</span></a>
</dt>
</#list>
</@cms_chanel_list>
自定定義指令
首先要實現TemplateDirectiveModel介面。
public class ChanelListDirective implements TemplateDirectiveModel {
@Inject
private ChanelDao chanelDao;
/*
* @param 傳入的引數,params型別為Map<String,
* TemplateModel>,由於歷史原因沒用泛型。比如傳入引數“count=5”,String為count,TemplateModel為5
*
* @loopVars 迴圈變數
*
* @see freemarker.template.TemplateDirectiveModel#execute(freemarker.core.
* Environment, java.util.Map, freemarker.template.TemplateModel[],
* freemarker.template.TemplateDirectiveBody)
*/
public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
// TODO Auto-generated method stub
if (params == null || params.size() == 0) {
throw new TemplateException("params can not be empty", env);
}
int count = 0;
String excludeStr = null;
// 處理傳入的引數
for (Object key : params.keySet()) {
String name = (String) key;
if (name.equalsIgnoreCase("count")) {
if (params.get(key) instanceof TemplateNumberModel)
count = ((TemplateNumberModel) params.get(key)).getAsNumber().intValue();
else
throw new TemplateException("count param must be number", env);
}
if (name.equalsIgnoreCase("exclude")) {
if (params.get(key) instanceof TemplateScalarModel)
excludeStr = ((TemplateScalarModel) params.get(key)).getAsString();
else
throw new TemplateException("execlude param must be string", env);
}
}
List<Chanel> chanleList = chanelDao.loadAll();
List<Chanel> list = new ArrayList<>();
for (int i = 0; i < count && i < chanleList.size(); i++) {
if (chanleList.get(i).getName().equals(excludeStr))
continue;
list.add(chanleList.get(i));
}
env.setVariable("chllist", ObjectWrapper.DEFAULT_WRAPPER.wrap(list));
if (body != null) {
body.render(env.getOut());
}
}
}
在freemarker中配置
需要繫結該指令為cms_chanel_list
...
<bean id="chanelListDirective" class="com.ydoing.web.directives.ChanelListDirective"/>
<!-- 配置freeMarker的模板路徑 -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/t/cms/www/default/" />
<property name="defaultEncoding" value="UTF-8" />
<property name="freemarkerVariables">
<map>
<entry key="cms_chanel_list" value-ref="chanelListDirective"/>
</map>
</property>
...