1. 程式人生 > >Freemarker自定義指令

Freemarker自定義指令

場景

在做一個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> 
    ...