freemarker中實現自定義標籤(包含處理參數以及循環變量)

 

 

  1 import java.io.IOException;   
  2  import java.io.Writer;   
  3  import java.util.Iterator;   
  4  import java.util.Map;   
  5   
  6  import freemarker.core.Environment;   
  7 import freemarker.template.SimpleNumber;   
  8 import freemarker.template.TemplateBooleanModel;   
  9 import freemarker.template.TemplateDirectiveBody;   
 10 import freemarker.template.TemplateDirectiveModel;   
 11 import freemarker.template.TemplateException;   
 12 import freemarker.template.TemplateModel;   
 13 import freemarker.template.TemplateModelException;   
 14 import freemarker.template.TemplateNumberModel;   
 15   
 16 /**  
 17  * FreeMarker 自定義標籤實現重複輸出內容體。  
 18  *   
 19  *   
 20  * 參數:  
 21  * count: 重複的次數,必須的且非負整數。  
 22  * hr: 設置是否輸出HTML標籤 "hr" 元素. Boolean. 可選的默認爲fals.  
 23  *   
 24  *   
 25  * 循環變量: 只有一個,可選的. 從1開始。  
 26  *   
 27  *   
 28  */  
 29 public class RepeatDirective implements TemplateDirectiveModel {   
 30   
 31     private static final String PARAM_NAME_COUNT = "count";   
 32     private static final String PARAM_NAME_HR = "hr";   
 33   
 34     public void execute(Environment env, Map params, TemplateModel[] loopVars,   
 35             TemplateDirectiveBody body) throws TemplateException, IOException {   
 36   
 37         // ---------------------------------------------------------------------   
 38         // 處理參數   
 39   
 40         int countParam = 0;   
 41         boolean countParamSet = false;   
 42         boolean hrParam = false;   
 43   
 44         Iterator paramIter = params.entrySet().iterator();   
 45         while (paramIter.hasNext()) {   
 46             Map.Entry ent = (Map.Entry) paramIter.next();   
 47   
 48             String paramName = (String) ent.getKey();   
 49             TemplateModel paramValue = (TemplateModel) ent.getValue();   
 50   
 51             if (paramName.equals(PARAM_NAME_COUNT)) {   
 52                 if (!(paramValue instanceof TemplateNumberModel)) {   
 53                     throw new TemplateModelException("The \"" + PARAM_NAME_HR   
 54                             + "\" parameter " + "must be a number.");   
 55                 }   
 56                 countParam = ((TemplateNumberModel) paramValue).getAsNumber()   
 57                         .intValue();   
 58                 countParamSet = true;   
 59                 if (countParam < 0) {   
 60                     throw new TemplateModelException("The \"" + PARAM_NAME_HR   
 61                             + "\" parameter " + "can't be negative.");   
 62                 }   
 63             } else if (paramName.equals(PARAM_NAME_HR)) {   
 64                 if (!(paramValue instanceof TemplateBooleanModel)) {   
 65                     throw new TemplateModelException("The \"" + PARAM_NAME_HR   
 66                             + "\" parameter " + "must be a boolean.");   
 67                 }   
 68                 hrParam = ((TemplateBooleanModel) paramValue).getAsBoolean();   
 69             } else {   
 70                 throw new TemplateModelException("Unsupported parameter: "  
 71                         + paramName);   
 72             }   
 73         }   
 74         if (!countParamSet) {   
 75             throw new TemplateModelException("The required \""  
 76                     + PARAM_NAME_COUNT + "\" paramter" + "is missing.");   
 77         }   
 78   
 79         if (loopVars.length > 1) {   
 80             throw new TemplateModelException(   
 81                     "At most one loop variable is allowed.");   
 82         }   
 83   
 84         // Yeah, it was long and boring...   
 85   
 86         // ---------------------------------------------------------------------   
 87         // 真正開始處理輸出內容   
 88   
 89         Writer out = env.getOut();   
 90         if (body != null) {   
 91             for (int i = 0; i < countParam; i++) {   
 92                 // 輸出  <hr> 若是 參數hr 設置爲true   
 93                 if (hrParam && i != 0) {   
 94                     out.write("<hr>");   
 95                 }   
 96   
 97                 // 設置循環變量   
 98                 if (loopVars.length > 0) {   
 99                     loopVars[0] = new SimpleNumber(i + 1);   
100                 }   
101   
102                 // 執行標籤內容(same as <#nested> in FTL).    
103                 body.render(env.getOut());   
104             }   
105         }   
106     }   
107   
108 }  

 

 1 import java.io.File;   
 2 import java.io.IOException;   
 3 import java.io.Writer;   
 4 import java.util.Map;   
 5   
 6 import freemarker.template.Configuration;   
 7 import freemarker.template.DefaultObjectWrapper;   
 8 import freemarker.template.Template;   
 9 import freemarker.template.TemplateException;   
10   
11 /**  
12  *   
13  * 模板工具類  
14  */  
15 public class FreeMarkertUtil {   
16     /**  
17      * @param templatePath 模板文件存放目錄   
18      * @param templateName 模板文件名稱   
19      * @param root 數據模型根對象  
20      * @param templateEncoding 模板文件的編碼方式  
21      * @param out 輸出流  
22      */  
23     public static void processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){   
24         try {   
25             Configuration config=new Configuration();   
26             File file=new File(templatePath);   
27             //設置要解析的模板所在的目錄,並加載模板文件   
28             config.setDirectoryForTemplateLoading(file);   
29             //設置包裝器,並將對象包裝爲數據模型   
30             config.setObjectWrapper(new DefaultObjectWrapper());   
31                
32             //獲取模板,並設置編碼方式,這個編碼必需要與頁面中的編碼格式一致   
33             Template template=config.getTemplate(templateName,templateEncoding);   
34             //合併數據模型與模板   
35                
36             template.process(root, out);   
37             out.flush();   
38             out.close();   
39         } catch (IOException e) {   
40             e.printStackTrace();   
41         }catch (TemplateException e) {   
42             e.printStackTrace();   
43         }   
44            
45     }    
46 }  

 

 

 1 import java.io.OutputStreamWriter;   
 2 import java.util.HashMap;   
 3 import java.util.Map;   
 4   
 5 /**  
 6  *   
 7  * 客戶端測試模板輸入類  
 8  */  
 9 public class RepeatTest {   
10     public static void main(String[] args) {   
11         Map<String,Object> root=new HashMap<String, Object>();   
12   
13         root.put("repeat", new RepeatDirective());   
14            
15         FreeMarkertUtil.processTemplate("src/templates","repeat.ftl", "UTF-8", root, new OutputStreamWriter(System.out));   
16            
17     }   
18 }  

 

 

 

 1  模板文件repeat.ftl以下:
 2 
 3  
 4 
 5 <#assign x = 1>   
 6   
 7 一個參數:   
 8 <@repeat count=4>   
 9   Test ${x}   
10   <#assign x = x + 1>   
11 </@repeat>   
12   
13 二個參數:   
14 <@repeat count=3 hr=true>   
15   Test   
16 </@repeat>   
17   
18 循環變量:   
19 <@repeat count=3; cnt>   
20   ${cnt}. Test   

 

 輸出結果:java

Java代碼
  1. 一個參數:   
  2.   Test 1  
  3.   Test 2  
  4.   Test 3  
  5.   Test 4  
  6.   
  7. 二個參數:   
  8.   Test   
  9. <hr>  Test   
  10. <hr>  Test   
  11.   
  12. 循環變量:   
  13.   1. Test   
  14.   2. Test   
  15.   3. Test
相關文章
相關標籤/搜索