Freemaker 自定義指令和函數


自定義函數和指令都可以在前台或者后台進行指定。

個人理解:指令的作用,主要是進行頁面調整之后進行輸出;函數的作用,主要是為了進行運算,返回運算結果供前台展示。

(一) 自定義指令

使用以下格式調用自定義指令:

<@user_def_dir_exp param1=val1 param2=val2 ... paramN=valN/>

定義在前台:

<#macro name param1 param2 ... paramN>
    ...
    <#nested loopvar1, loopvar2, ..., loopvarN>
     ...
    <#return>
    ...
</#macro>

例子:

<#macro test foo bar baaz>
    Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<#-- call the macro: -->
<@test foo="a" bar="b" baaz=5*5-2/>

輸出結果:

Test text, and the params: a, b, 23

定義在后台:

Java程序員可以使用TemplateDirectiveModel接口在Java代碼中實現自定義指令。詳情可以參加API文檔。
注意:
TemplateDirectiveModel在FreeMarker 2.3.11版本時才加入。用來代替快被廢棄的TemplateTransformModel。

public class UpperDirective implements TemplateDirectiveModel {
     public void execute(Environment env, Map params,
           TemplateModel[] loopVars, TemplateDirectiveBody body)  throws TemplateException, IOException {
          // 檢查參數是否傳入
         if (!params.isEmpty()) {
                 throw new TemplateModelException("This directive doesn't allow parameters.");
         }
        if (loopVars.length != 0) {
               throw new TemplateModelException("This directive doesn't allow loop variables.");
        }
       // 是否有非空的嵌入內容
      if (body != null) {
           // 執行嵌入體部分,和FTL中的<#nested>一樣,除了
           // 我們使用我們自己的writer來代替當前的output writer.
           body.render(new UpperCaseFilterWriter(env.getOut()));
      } else {
          throw new RuntimeException("missing body");
     }
}
/**
* {@link Writer}改變字符流到大寫形式,
* 而且把它發送到另外一個{@link Writer}中。
*/
private static class UpperCaseFilterWriter extends Writer {
        private final Writer out;
       UpperCaseFilterWriter (Writer out) {
            this.out = out;
        }
       public void write(char[] cbuf, int off, int len)
                 throws IOException {
          char[] transformedCbuf = new char[len];
          for (int i = 0; i < len; i++) {
              transformedCbuf[i] = Character.
              toUpperCase(cbuf[i + off]);
         }
        out.write(transformedCbuf);
       }

       public void flush() throws IOException {
           out.flush();
       }
}
例子:

foo
<@upper>
  bar
  <#-- 這里允許使用所有的FTL -->
     <#list ["red", "green", "blue"] as color>
       ${color}
      </#list>
   baaz
</@upper>
wombat

輸出結果:

foo
   BAR
      RED
      GREEN
      BLUE
   BAAZ
wombat

(二) 自定義函數

使用類似格式  ${avg(10, 20)}  其中avg為函數名,10,20為傳入的參數

定義在前台:

<#function name param1 param2 ... paramN>
   ...
  <#return returnValue>
  ...
</#function>

例子:

<#function avg x y>
    <#return (x + y) / 2>
</#function>

輸出結果:

15

定義在后台:

        方法變量在存於實現了TemplateMethodModel接口的模板中。這個接口僅包含一個方法:TemplateModel exec(java.util.List arguments)。當使用方法調用表達式調用方法時,exec方法將會被調用。形參將會包含FTL方法調用形參的值。exec方法的返回值給出了FTL方法調用表達式的返回值。
         TemplateMethodModelEx接口擴展了TemplateMethodModel接口。它沒有任何新增的方法。事實上這個對象實現這個標記接口暗示給FTL引擎,形式參數應該直接以TemplateModel-s形式放進java.util.List。否則將會以String-s形式放入List。

public class IndexOfMethod implements TemplateMethodModel {
        public TemplateModel exec(List args) throws TemplateModelException {
               if (args.size() != 2) {
                     throw new TemplateModelException("Wrong arguments");
                }
              return new SimpleNumber(((String) args.get(1)).indexOf((String) args.get(0))); 
       }
}

然后將實例放入到根數據模型中:

root.put("indexOf", new IndexOfMethod());

例子:

<#assign x = "something">
${indexOf("met", x)}
${indexOf("foo", x)}

輸出結果:

2
-1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM