(本系列參考了大量玄玉大神博客)
首先是java代碼:
package com.joker.test;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class TestMrco {
public static void main(String[] args) {
String templateLoaderPath = "/";
String templateName = "testMrco.ftl";
Configuration cfg = new Configuration();
String htmlPath = "D:/freemakerTest";
String htmlName = "testMrco.html";
Writer out = null;
Map<String, Object> parms = new HashMap<String, Object>();
User user1 = new User();
user1.setName("反戰聯盟");
ArrayList<String>names = new ArrayList<String>();
names.add("name1");
names.add("name2");
names.add("name3");
user1.setNames(names);
parms.put("user", user1);
parms.put("varName", "varNameInModel");
try {
cfg.setClassForTemplateLoading(TestMrco.class, templateLoaderPath);
Template temp = cfg.getTemplate(templateName);
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(htmlPath + "/" + htmlName), "UTF-8"));
temp.process(parms, out);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
String templateLoaderPath = "/";
String templateName = "testMrco.ftl";
Configuration cfg = new Configuration();
String htmlPath = "D:/freemakerTest";
String htmlName = "testMrco.html";
Writer out = null;
Map<String, Object> parms = new HashMap<String, Object>();
User user1 = new User();
user1.setName("反戰聯盟");
ArrayList<String>names = new ArrayList<String>();
names.add("name1");
names.add("name2");
names.add("name3");
user1.setNames(names);
parms.put("user", user1);
parms.put("varName", "varNameInModel");
try {
cfg.setClassForTemplateLoading(TestMrco.class, templateLoaderPath);
Template temp = cfg.getTemplate(templateName);
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(htmlPath + "/" + htmlName), "UTF-8"));
temp.process(parms, out);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
然後是重要的ftl文件:
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<style>
span{
color:red;
}
</style>
</head>
<body>
<#--定義宏-->
<#macro writeNote str1>
<span color="red">${str1}</span>
</#macro>
<#macro testMacro>
<h1> hello </h1>
</#macro>
<@testMacro></@testMacro>
<#macro testParm person>
<h2>hello ${person}<h2>
</#macro>
<@testParm "123"></@testParm>
<@writeNote "可以使用 user.name這種形式獲取參數值,而不再需要EL表達式輸出"></@writeNote>
<@testParm user.name></@testParm>
${r'${r""}'}這種形式的轉義可以輸出EL表達式
${"<br>"?html} ${"在html元素後面加上?html可以直接輸出元素標籤"}
<#macro testDeafult text="可以對參數設置默認值">
<h1>${text}</h1>
</#macro>
<@testDeafult></@testDeafult>
<@testDeafult "test"></@testDeafult>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<style>
span{
color:red;
}
</style>
</head>
<body>
<#--定義宏-->
<#macro writeNote str1>
<span color="red">${str1}</span>
</#macro>
<#macro testMacro>
<h1> hello </h1>
</#macro>
<@testMacro></@testMacro>
<#macro testParm person>
<h2>hello ${person}<h2>
</#macro>
<@testParm "123"></@testParm>
<@writeNote "可以使用 user.name這種形式獲取參數值,而不再需要EL表達式輸出"></@writeNote>
<@testParm user.name></@testParm>
${r'${r""}'}這種形式的轉義可以輸出EL表達式
${"<br>"?html} ${"在html元素後面加上?html可以直接輸出元素標籤"}
<#macro testDeafult text="可以對參數設置默認值">
<h1>${text}</h1>
</#macro>
<@testDeafult></@testDeafult>
<@testDeafult "test"></@testDeafult>
<#macro testNested>
<#nested>
<#nested>
</#macro>
<#nested>
<#nested>
</#macro>
<@testNested>
<@writeNote "${r'<#nested>'} 執行調用宏代碼和結束調用宏之間的代碼,可以理解爲將 @testNested 和 /@testNested 之間的內容 nested 進宏. 所以${r'<#nested>'} 出現了幾次,就會輸出幾次<br>">
</@writeNote>
</@testNested>
<#macro testNestedWitParm>
<#nested user.name user.name>
</#macro>
<@testNestedWitParm; x,y>
我的x是${x},我的y是${y}
</@testNestedWitParm>
<#macro test1>
<@writeNote '我是被嵌套的代碼開始'></@writeNote>
<#nested>
<@writeNote '我是被嵌套的代碼結束'></@writeNote>
</#macro>
<#macro test2>
"我是嵌套的代碼開始"
"我是嵌套的代碼結束"
</#macro>
--------------------------------
<@test1>
<@test2>
</@test2>
</@test1>
-------------------
<#assign testBoolean=true/>
${testBoolean?string("true","false")}
----------
<@writeNote "freemaker四種類型的變量 模型變量--存在於rootMap中的變量,模板變量---assign的變量,變量----存在於指令中的變量,循環變量,存在於循環體中的變量"/>
${r"{.globals.XXX}這種方式是直接查找模型變量否則是先去模板變量中尋找XXX,如果沒有,則去模型變量中尋找"}:${.globals.varName}
<@writeNote "${r'<#nested>'} 執行調用宏代碼和結束調用宏之間的代碼,可以理解爲將 @testNested 和 /@testNested 之間的內容 nested 進宏. 所以${r'<#nested>'} 出現了幾次,就會輸出幾次<br>">
</@writeNote>
</@testNested>
<#macro testNestedWitParm>
<#nested user.name user.name>
</#macro>
<@testNestedWitParm; x,y>
我的x是${x},我的y是${y}
</@testNestedWitParm>
<#macro test1>
<@writeNote '我是被嵌套的代碼開始'></@writeNote>
<#nested>
<@writeNote '我是被嵌套的代碼結束'></@writeNote>
</#macro>
<#macro test2>
"我是嵌套的代碼開始"
"我是嵌套的代碼結束"
</#macro>
--------------------------------
<@test1>
<@test2>
</@test2>
</@test1>
-------------------
<#assign testBoolean=true/>
${testBoolean?string("true","false")}
----------
<@writeNote "freemaker四種類型的變量 模型變量--存在於rootMap中的變量,模板變量---assign的變量,變量----存在於指令中的變量,循環變量,存在於循環體中的變量"/>
${r"{.globals.XXX}這種方式是直接查找模型變量否則是先去模板變量中尋找XXX,如果沒有,則去模型變量中尋找"}:${.globals.varName}
<br>模型變量${r"${varName}"}:${varName}
<br>模型變量${r"<#assign varName=>"}:<#assign varName="varInModelPlant">:${varName}
<br> 所以這種方式有問題,問題在於可能將模型變量覆蓋,所以產生了存在於宏中的變量,局部變量
<#macro testVarName>
<#local varName="varInMacro">
使用${r"<#local varName= 'varInMacro'"}對varName賦值 所以varName 變量只存在於 macro中${varName}
</#macro>
<br>
而執行完畢的varName還是${varName},不受macro中的影響
<@testVarName/>
此時外面的${r"${varName}的值爲:"} ${varName}
<br>模型變量${r"<#assign varName=>"}:<#assign varName="varInModelPlant">:${varName}
<br> 所以這種方式有問題,問題在於可能將模型變量覆蓋,所以產生了存在於宏中的變量,局部變量
<#macro testVarName>
<#local varName="varInMacro">
使用${r"<#local varName= 'varInMacro'"}對varName賦值 所以varName 變量只存在於 macro中${varName}
</#macro>
<br>
而執行完畢的varName還是${varName},不受macro中的影響
<@testVarName/>
此時外面的${r"${varName}的值爲:"} ${varName}
<br>最後一個是循環變量,該作用範圍只在循環內,不會影響外面的${r"${varName}"}:
<#list user.names as varName>
<br>
循環體內的值爲:${varName}
</#list>
<br>
此時外面的${r"${varName}的值爲:"}${varName}
</body>
</html>
<#list user.names as varName>
<br>
循環體內的值爲:${varName}
</#list>
<br>
此時外面的${r"${varName}的值爲:"}${varName}
</body>
</html>
最後是運行結果:
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<style>
span{
color:red;
}
</style>
</head>
<body>
<h1> hello </h1>
<h2>hello 123<h2>
<span color="red">可以使用 user.name這種形式獲取參數值,而不再需要EL表達式輸出</span>
<h2>hello 反戰聯盟<h2>
${r""}這種形式的轉義可以輸出EL表達式
<br> 在html元素後面加上?html可以直接輸出元素標籤
<h1>可以對參數設置默認值</h1>
<h1>test</h1>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<style>
span{
color:red;
}
</style>
</head>
<body>
<h1> hello </h1>
<h2>hello 123<h2>
<span color="red">可以使用 user.name這種形式獲取參數值,而不再需要EL表達式輸出</span>
<h2>hello 反戰聯盟<h2>
${r""}這種形式的轉義可以輸出EL表達式
<br> 在html元素後面加上?html可以直接輸出元素標籤
<h1>可以對參數設置默認值</h1>
<h1>test</h1>
<span color="red"><#nested> 執行調用宏代碼和結束調用宏之間的代碼,可以理解爲將 @testNested 和 /@testNested 之間的內容 nested 進宏. 所以<#nested> 出現了幾次,就會輸出幾次<br></span>
<span color="red"><#nested> 執行調用宏代碼和結束調用宏之間的代碼,可以理解爲將 @testNested 和 /@testNested 之間的內容 nested 進宏. 所以<#nested> 出現了幾次,就會輸出幾次<br></span>
我的x是反戰聯盟,我的y是反戰聯盟
--------------------------------
<span color="red">我是被嵌套的代碼開始</span>
"我是嵌套的代碼開始"
"我是嵌套的代碼結束"
<span color="red">我是被嵌套的代碼結束</span>
-------------------
true
----------
<span color="red">freemaker四種類型的變量 模型變量--存在於rootMap中的變量,模板變量---assign的變量,變量----存在於指令中的變量,循環變量,存在於循環體中的變量</span>
{.globals.XXX}這種方式是直接查找模型變量否則是先去模板變量中尋找XXX,如果沒有,則去模型變量中尋找:varNameInModel
<br>模型變量${varName}:varNameInModel
<br>模型變量<#assign varName=>::varInModelPlant
<br> 所以這種方式有問題,問題在於可能將模型變量覆蓋,所以產生了存在於宏中的變量,局部變量
<br>
而執行完畢的varName還是varInModelPlant,不受macro中的影響
使用<#local varName= 'varInMacro'對varName賦值 所以varName 變量只存在於 macro中varInMacro
此時外面的${varName}的值爲: varInModelPlant
<br>模型變量<#assign varName=>::varInModelPlant
<br> 所以這種方式有問題,問題在於可能將模型變量覆蓋,所以產生了存在於宏中的變量,局部變量
<br>
而執行完畢的varName還是varInModelPlant,不受macro中的影響
使用<#local varName= 'varInMacro'對varName賦值 所以varName 變量只存在於 macro中varInMacro
此時外面的${varName}的值爲: varInModelPlant
<br>最後一個是循環變量,該作用範圍只在循環內,不會影響外面的${varName}:
<br>
循環體內的值爲:name1
<br>
循環體內的值爲:name2
<br>
循環體內的值爲:name3
<br>
此時外面的${varName}的值爲:varInModelPlant
</body>
</html>
<br>
循環體內的值爲:name1
<br>
循環體內的值爲:name2
<br>
循環體內的值爲:name3
<br>
此時外面的${varName}的值爲:varInModelPlant
</body>
</html>