2.1import指令
該指令用於導入FreeMarker模板中的所有變量,並將該變量放置在指定的Map對象中,import指令的語法格式如下:
<#import “/lib/common.ftl” as xxx>
上面的代碼將導入/lib/common.ftl模板文件中的所有變量,交將這些變量放置在一個名爲xxx的Map對象中.
2.2 macro的使用
這個可以用來實現自定義指令,一般用來做公共組件,我們稱之爲宏
2.3macro與import組合實現下拉列表模板組件
2.3.1需求說明
很多網站都有會員等級,這裏我們假設有三個等級,【金牌會員,銀牌會員,普通會員】,這只是顯示的text,真正存儲會員等級字段應該是一個字符編碼,比如數字或一個字符串,我們成爲編碼cd。
現在我們使用macro與import組合實現下拉列表模板組件,並會員等級實現下拉列表。這種統一的模板組件對於開發效率來說是非常有必要的。
2.3.1下拉列表宏構建
新建一個_custom_macros.ftl文件,內容如下
<#-- 下拉框:mode:""全部,1請選擇 -->
<#macro select id name="" value="" mode="" class="drop" style="width:100px" disabled="">
<#if name == "">
<#local localName=id/>
<#else>
<#local localName=name/>
</#if>
<select id=${id} name=${localName} class=${class} style=${style} panelHeight=":auto" ${disabled}>
<#if mode == "">
<option value="">-- 全部 --</option>
<#elseif mode == "1">
<option value="">-- 請選擇 --</option>
<#else>
</#if>
<#if codeList?? && codeList?size > 0>
<#list codeList as code>
<option value="${code.codeCd}" <#if code.codeCd == value> selected </#if>>${code.codeText!''}</option>
</#list>
</#if>
</select>
</#macro>
說明:
(1)<#macro select id name="" value="" mode="" class="drop" style="width:100px" disabled="">
定義了這個宏接受的參數列表並對某些參數進行了初始化,其中,mode爲控制下拉列表默認顯示樣式,邏輯一眼就能看出來,就不多說了。
(2)<#macro 後跟的第一個字符會被認爲是該宏的別名,調用的時候會根據這個別名調用,這裏起名爲select。
(2)我們這裏寫死了,取參數codeList中的值作爲下拉列表的內容填充,真正這個地方的數據填充從什麼地方獲取,我們稍後再說,這裏先寫死。
2.3.2codeList數據準備
(1)在項目中我們根據會員的codecd及codetest設計一個pojo名爲code
/**
* @author suyouliang
* @version v1.0 2018年08月21日 18:00
* 這是一個字典對象
*/
public class Code {
private String codeCd;
private String codeText;
public String getCodeCd() {
return codeCd;
}
public void setCodeCd(String codeCd) {
this.codeCd = codeCd;
}
public String getCodeText() {
return codeText;
}
public void setCodeText(String codeText) {
this.codeText = codeText;
}
}
(2)數據準備
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author suyouliang
* @version v1.0 2018年08月21日 17:17
*/
public class FreemarkerDemo {
public static void main(String[] args) throws Exception {
//1.創建配置類
Configuration configuration=new Configuration(Configuration.getVersion());
//2.設置模板所在的目錄
configuration.setDirectoryForTemplateLoading(new File("D:\\freemarkerdemo"));
//3.設置字符集
configuration.setDefaultEncoding("utf-8");
//4.加載模板
Template template = configuration.getTemplate("test.ftl");
//5.創建數據模型
Map map=new HashMap();
initCodeList(map);
//6.創建Writer對象
Writer out =new FileWriter(new File("D:\\freemarkerdemo\\test.html"));
//7.輸出
template.process(map, out);
//8.關閉Writer對象
out.close();
}
private static void initCodeList(Map map) {
List<Code> codeList = new ArrayList();
Code code1 = new Code();
Code code2 = new Code();
Code code3 = new Code();
code1.setCodeCd("1");
code1.setCodeText("普通會員");
code2.setCodeCd("2");
code2.setCodeText("銀牌會員");
code3.setCodeCd("3");
code3.setCodeText("黃金會員");
codeList.add(code1);
codeList.add(code2);
codeList.add(code3);
map.put("codeList", codeList);
}
}
這樣,我們就在模板引擎中放入了codeList對象。
2.3.3在頁面中使用宏
<#import "_custom_macros.ftl" as cont>
<html>
<head xmlns="http://www.w3.org/1999/html">
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
<#--我是一個註釋,我不會有任何輸出 -->
<!--我也是個註釋,但是我會在生成的文件中輸出-->
</br>
<p>多選框:<@cont.select id="member_grade" value="2"/></p>
</body></html>
說明:
(1)首先先通過<#import >指令導入我們定義好的下拉列表的宏,並起別名爲cont方便使用
(2)通過<@cont.select>語法調用宏 其中,cont是我們自己起的別名,@+別名是規定的語法,select就是我們自己在宏中定義的宏的名稱。
這裏我們初始化了宏中定義的id,以及value,根據2.3.1中的邏輯,,這裏其實是定義了下拉列表的value和默認選項。由於沒有定義mode的值,在value爲空的時候,默認顯示的方式是“--全部--”,當指定mode值爲1是,就可以更改爲“--請選擇--”,宏中邏輯很容易看出來。
我們運行main方法,生成的test.html如下:
<html>
<head xmlns="http://www.w3.org/1999/html">
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
<!--我也是個註釋,但是我會在生成的文件中輸出-->
</br>
<p>多選框:<select id=member_grade name=member_grade class=drop style=width:100px panelHeight=":auto" >
<option value="">-- 全部 --</option>
<option value="1" >普通會員</option>
<option value="2" selected >銀牌會員</option>
<option value="3" >黃金會員</option>
</select>
</p>
</body></html>
在網頁中打開效果:
默認就是銀牌會員。
2.3.4宏功能擴展
我們可以把日常用的,單選,多選,日曆甚至分頁宏加入我們的宏邏輯中
<#-- 下拉框:mode:""全部,1請選擇 -->
<#macro select id name="" value="" mode="" class="drop" style="width:100px" disabled="">
<#if name == "">
<#local localName=id/>
<#else>
<#local localName=name/>
</#if>
<select id=${id} name=${localName} class=${class} style=${style} panelHeight="auto" ${disabled}>
<#if mode == "">
<option value="">-- 全部 --</option>
<#elseif mode == "1">
<option value="">-- 請選擇 --</option>
<#else>
</#if>
<#if codeList?? && codeList?size > 0>
<#list codeList as code>
<option value="${code.codeCd}" <#if code.codeCd == value> selected </#if>>${code.codeText!''}</option>
</#list>
</#if>
</select>
</#macro>
<#-- 單選鈕 -->
<#macro radio id name="" value="" class="rad" isDefault = "true" disabled="">
<#if name == "">
<#local localName=id/>
<#else>
<#local localName=name/>
</#if>
<#if codeList?? && codeList?size > 0>
<#list codeList as code>
<input type="radio" id="${id}" name="${localName}" class="${class}" value="${code.codeCd}" <#if code.codeCd == value || (isDefault == 'true' && value == '' && code_index == 0)> checked </#if> ${disabled}/> ${code.codeText}
</#list>
</#if>
</#macro>
<#-- 複選鈕 -->
<#macro checkbox id name="" value=[] >
<#if name == "">
<#local localName=id/>
<#else>
<#local localName=name/>
</#if>
<#list codeList as code>
<#local checked=""/>
<#list value as val>
<#if val == code.codeCd>
<#local checked="checked"/>
<#break>
</#if>
</#list>
<input type="checkbox" id="${id}" name="${localName}" value="${code.codeCd}" class="chk" ${checked} /> ${code.codeText}
</#list>
</#macro>
<#-- 日曆控件 -->
<#macro calendar id name="" value="">
<#if name == "">
<#local localName=id/>
<#else>
<#local localName=name/>
</#if>
<input type="text" id="${id}" name="${localName}" value="${value}" class="Wdate" />
</#macro>
2.4freemarker的宏在實際開發中的應用場景
以上提到,codeList是我們定義死的,這個顯然是不合理的,那麼以上例子在實際開發中的應用場景到底是什麼樣的呢。
2.4.1字典應用場景
企業開發中字典被廣泛應用,一般主要是一個codeCd和一個codeText,我們在給這一組字典起名爲codeNamecode,將該字典封裝爲到叫code的pojo。字典的使用會使我們相關的顯示更加靈活,就比如上面舉的會員等級text,有一天老闆說:“叫金牌會員,銀牌會員太土了,改叫尊享會員和至尊會員吧” 你:“啊啊?” 這麼多頁面,相信你會改到懷疑人生。
在使用字典的項目中,使用以上的宏將非常有意義,他可以確保所有的顯示都是引用字典中定義的,一旦需要修改,只需要更改字典中的text即可。
我們可以定義一個CodeManager用來管理字典表,這個類啓動時加載,加載時查詢數據庫中的字典表並裝到內存(或外部緩存)中(爛尾文章,前面還是很實用的)