自定義函數和指令均可以在前臺或者後臺進行指定。 html
我的理解:指令的做用,主要是進行頁面調整以後進行輸出;函數的做用,主要是爲了進行運算,返回運算結果供前臺展現。 java
使用如下格式調用自定義指令: 程序員
<@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/>
輸出結果: oop
Test text, and the params: a, b, 23
Java程序員可使用TemplateDirectiveModel接口在Java代碼中實現自定義指令。詳情能夠參加API文檔。
注意:
TemplateDirectiveModel在FreeMarker 2.3.11版本時才加入。用來代替快被廢棄的TemplateTransformModel。 this
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
輸出結果: spa
使用相似格式 ${avg(10, 20)} 其中avg爲函數名,10,20爲傳入的參數 code
<#function name param1 param2 ... paramN> ... <#return returnValue> ... </#function>
例子: orm
<#function avg x y> <#return (x + y) / 2> </#function>
輸出結果: htm
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