.FreeMarker介紹
FreeMarker是一種模板引擎,通過定義的模板和數據來生成文本(包括但不局限于html,js,java等文本格式),通俗的講就是先定義一下模板,然后傳入不同的數據,動態的生成不同的文本,但它不是面向用戶的,而是面向程序員的,可以直接自動的生成代碼,減少程序員重復的勞動。FreeMarker最重要的兩部分是模板和數據:模板:FreeMarker Template Language,簡稱FTL,模板文件以ftl為后綴,組成:
文本,包括HTML標簽與靜態文本等靜態內容,會原樣輸出;
插值:這部分的輸出會被計算的數據來替換,使用${}這種語法;
標簽:給FreeMarker的指示,可以簡單與指令等同,不會打印在內容中;
注釋:由<#--和-->表示,不會被freemarker處理 數據結構: 樹狀結構:HashMap,Scalar,Sequence
2.基本使用
從http://freemarker.org/ 下載FreeMarker的壓縮包,將其中的freemarker.jar加到項目的構建路徑下從maven倉庫中引入maven依賴的jar包,注意兩個核心類:
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.24-atlassian-2</version></dependency>
Configuration:讀取模板文件
Template:模板
Configuration cfg = new Configuration(Configuration.VERSION_2_3_21); Map<String,String> root= new HashMap<String,String>(); root.put("name", "Java開發日記"); try { cfg.setDirectoryForTemplateLoading(new File("src/ftl")); Template template = cfg.getTemplate("helloworld.ftl"); Writer writer = new FileWriter(new File("src/finish/helloworld.html")); template.process(root, writer); } catch (Exception e) { e.printStackTrace(); }
使用Configuration讀取配置文件,使用Map填充數據,給配置文件配置模板文件夾路徑,讀取模板文件,設置輸出文件路徑helloworld.html,執行輸出文件,執行完之后就會在src目錄下的finish文件夾中生成一個helloworld的html文件。模板文件如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>${name}</title></head><body>這是我的第一個程序,${name}</body></html>
3.模板
3.1 數據類型與變量
模板中的數據類型:
標量:字符串,數字,布爾值,日期;
容器:哈希表,序列;
子程序:方法和函數,用戶自定義指令; 模板中的變量: 簡單變量,局部變量,循環變量,使用賦值指令:assign 示例:
<#assign num=10>${num}<#assign name="Java開發日記">${name}<#assign b=true>${b?c}<#assign map={"name":"張三","age":15}>${map.name}<#assign list = [1,3,5]>${list[2]}
freemarker中使用指令時必須要在指令前面用#(如果是自定義指令用@,后面說),assign指令是用來聲明變量的,注意:如果是布爾值,輸出時一定要帶?c,表示定義的變量是布爾值,不然會報錯。
3.2運算符
模板中支持運算符:
算術運算符
比較運算符
邏輯運算符
空值處理運算符
<#assign b=1==2>${b?c}<#assign b=1 gt 2>${b?c}
均輸出false,gt表示大于。
3.3 插值
插值是用來給插入具體值然后轉換為文本,說白了,插值就是使用${}在那占個坑。使用位置:
文本區(如
字符串表達式(如<#include "/footer/${company}.html">) 語法:${表達式} 注意:插值表達式的結果必須是字符串,數字或日期類型。
3.4指令
條件指令
<#assign score=50><#if score gt 90>優秀<#elseif score gt 70>良好<#elseif score gt 60>及格<#else>渣渣</#if><#assign level="B"><#switch level> <#case "A"> 優秀 <#break > <#case "B"> 良好 <#break > <#case "C"> soso <#break > <#default> 渣渣</#switch>
需要注意的是switch語句需要有break,不然一直往下執行。
循環指令
<#assign nums=[1,2,3,4,5]><#list nums as num> ${num_index},${num},${num_has_next?c}</#list><#list nums as num> ${num}<#if num_has_next>,</#if></#list>
定義一個集合nums,使用list指令遍歷,${別名index}獲取遍歷的索引值,${別名has_next}判斷后面是否還有值,根據這個特性,可以結合if指令拼接不同的值(自動生成mybatis的配置文件時,不同字段最后一個后面不要逗號,用這個特性很好用)。
包含指令
<#include "condition.ftl">從這里開始是自己的內容
使用include引入指令可以引入其它的模板頁面。如果頁面路徑寫不好可以用通配符,<#include "*/condition.ftl">
其它 原樣輸出指令noparse:它里面的內容是原樣輸出的; 壓縮指令compress:壓縮所有的空格; 設置指令setting:設置影響FreeMarker的值。
<#noparse> <#assign num=1> ${num}</#noparse><#assign s=" test \n\n"><#compress> ${s} Compress</#compress><#setting locale="hu">${1.2}
自定義指令 可以將模版中重復的內容進行復用 定義: 使用macro指令定義或者使用Java實現。 參數的聲明:直接跟在指令名后,可以指定默認值 嵌套內容:使用nested指令 調用: 使用<@指令>來調用(調用freemarker自帶的指令用#命令)。
<#macro mydirect name age=20> 你好,${name},你今年${age}</#macro><@mydirect name="Java開發日記" age=1/>
自定義一個指令名為mydirect,它有兩個參數name和age,其中age有默認值20,使用自定義指令時用@+自定義指令,同時為參數賦值即可。注意自定義指令是閉口的,不要漏掉最后的斜杠。
3.5 空處理
有時候對象是空的,不進行判斷就貿然進行處理會報錯,所以要提前進行判空處理。
null對象的處理方式:使用!,只會做最后一個屬性的判斷;
變量不存在的處理方式:使用!或??做判斷。
${user.name!}<#if user.name??> 名稱存在 <#else> 名稱不存在</#if>
我認為是在插值時使用!,在其它指令內使用??。
3.6名稱空間
在編寫可重復使用的模板時為了避免命名沖突,使用import指令導入命名空間。命名空間有點類似于java的包,即使類名相同,只要位于不同的包下,也是可以的。
test.ftl模板:<#macro mydirective name> 你好,${name}</#macro>namespace.ftl模板<#import "test.ftl" as ns><@ns.mydirective name="Java開發日記" />
在這里我定義兩個模板,在namespace.ftl中使用import指令導入test.ftl模板并為它起一個名為ns的命名空間,調用時我使用命令空間調用,即使namespace.ftl模板中有其它同名的也不至于混淆。另外在test.ftl中使用的是自定義指令定義了名為mydirective的指令,并為其制定一個參數name。
3.7函數
FreeMarker中函數有如下幾種:
字符串函數;
數字,日期布爾類型的函數;
序列(list,set)與哈希的函數;
自定義函數 而且FreeMarker中的函數與java中函數調用有個很大的區別,在java中調用函數使用點號(.),而在FreeMarker中使用問號(?),這一點一定要記清。下面分別說上面提到的幾種函數:
3.7.1字符串函數
${"abcdef"?substring(2)} <#--從角標是2的位置開始截取到字符串結束-->${"abcdef"?substring(2,4)} <#--從角標是2的位置開始截取到角標是4的位置,包括2不包括4(包前不包后)-->${"abcd mn"?cap_first} <#--將整個字符串的首字母轉大寫-->${"Abcd"?uncap_first} <#--將整個字符串的首字母轉小寫-->${"fden eb"?capitalize} <#--將字符串的每個單詞首字母轉大寫-->${"abcd"?ends_with("d")?c} <#--是否以字符d結尾,這個結果是布爾值,不能直接輸出,不然會報錯,用?c轉化成字符串-->${"abcd"?starts_with("d")?c} <#--是否以字符d開頭-->${"abac"?index_of("a")} <#--字符a首次出現的位置-->${"abac"?last_index_of("a")} <#--字符a最后一次出現的位置-->${"ab"?left_pad(15,"xy")} <#--將字符串ab填充成15位,如果不夠15位,則左邊循環填充xy-->${"ab"?right_pad(15,"xy")} <#--將字符串ab填充成15位,如果不夠15位,則右邊循環填充xy-->${"abac"?contains("ab")?c} <#--判斷字符串abac是否包含ab-->${"abac"?replace("ab","AB")} <#--將ab替換成AB--><#list "abcabcabc"?split("c") as s> ${s} <#--將字符串以c字符進行分割,結果是個數組,進行遍歷--></#list>${" abc "?trim} <#--去掉字符串空格--><#list " Hello FreeMarker Yes"?word_list as s>${s} <#--將字符串分割成一個個的單詞,存在多個空格時,這個跟上面的split分割有一點區別--></#list>
3.7.2數字,日期布爾類型的函數
${4.2?c} <#--以字符串的形式輸出,上面說的布爾類型不能直接輸出只能轉化成字符串這種-->${4.2?string} <#--與?c一樣-->${0.42?string.percent} <#--以百分號輸出42%-->${4.2?string.currency} <#--以貨幣形式輸出¥4.20-->${4.7?round} <#--四舍五入 -->${4.7?floor} <#--向下取整,floor地板 -->${4.7?ceiling} <#--向上取整,ceiling天花板-->${date?string("yyyy-MM-dd")} <#--傳入日期date,以yyyy-MM-dd形式輸出,2017-11-18-->${date?date} <#--輸出年月日2017-11-18-->${date?time} <#-- 輸出時分秒20:41:49-->${date?datetime} <#--輸出年月日時分秒-->${false?string("yes","no")} <#--條件如果成功輸出yes,否則輸出no-->${4.2355?string("0.##")} <#--保留小數點后兩位-->
3.7.3 序列(list,set)與哈希的函數
<#assign seq=[1,2,3,4,5,3,10]>${seq?first} <#-- 輸出序列seq的第一個-->${seq?last} <#-- 輸出序列seq的最后一個-->${seq?seq_contains(6)?c} <#--判斷序列是否包含6-->${seq?seq_index_of(3)} <#--3在序列中首次出現的位置-->${seq?seq_last_index_of(3)} <#--3在序列中最后一次出現的位置--><#list seq?reverse as num> <#--翻轉序列seq,結果還是一個序列,進行遍歷-->${num}</#list>${seq?size} <#--序列seq的長度--><#list seq?sort as num> <#--對序列進行排序-->${num}</#list><#assign seq1=[{"name":"Tom","age":23},{"name":"Jack","age":22},{"name":"Rose","age":21},{"name":"Tim","age":24}]><#list seq1?sort_by("age") as u> <#--以age對哈希seq1進行排序并遍歷-->${u.name}+","+${u.age}</#list><#assign users={"name":"Tim","age":24}><#list users?keys as key> <#--獲取到哈希users所有的鍵-->${key}</#list>
3.7.4 自定義函數
<#function add num1 num2> <#return num1+num2></#function><#function addAll nums...> <#local total=0> <#list nums as num> <#local total=total+num> </#list> <#return total></#function><#--使用function指令定義函數add,有兩個參數num1和num2,使用return返回計算之后的結果,使用${add(1,3)}調用函數 -->${add(1,3)}<#--使用function指令定義函數addAll,參數個數不固定,定義局部變量total來存儲臨時計算的結果,遍歷所有的參數并進行運算,使用return返回計算之后的結果,使用${addAll(1,2,3,4,5)}調用函數 -->${addAll(1,2,3,4,5)}
4.數據模型
4.1數據類型
使用基本數據類型來派生數字類型使用java.lang.String來構建字符串。使用java.lang.Number來派生數字類型。使用java.lang.Boolean來構建布爾值。使用java.util.List,java.util.Set或Java數組來構建序列。使用java.util.Map來構建哈希表。
Map root=new HashMap(); root.put("d1", 100); root.put("d2", 100.99); root.put("d3", 'a'); root.put("d4", true); root.put("d5", new Integer(200)); root.put("d6", new Boolean(false)); List<String> names= Arrays.asList("abc","def","ghi"); root.put("d7", names); Set<String> names1=new HashSet<>(); names1.add("ABC"); names1.add("DEF"); names1.add("GHI"); root.put("d8", names1); root.put("d9", new String[]{"a","b","c"}); Map map=new HashMap(); map.put("name", "Java開發日記"); map.put("age", 18); root.put("map", map);
就是java中常見的整型,浮點型,布爾型,字符,數組,list,set,map,不再多說
4.2 加載模板
使用Configuration的方法加載模版:1,void setDirectoryForTemplateLoading(File dir);2,void setClassForTemplateLoading(Class cl, String prefix);3,void setServletContextForTemplateLoading(Object servletContext, String path);加載多個位置的模版:1,FileTemplateLoader2,ClassTemplateLoader3,TemplateLoader4,MultiTemplateLoader5,setTemplateLoader(MultiTemplateLoader mtl);
Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); //cfg.setClassForTemplateLoading(TemplateLoad.class, "../../../ftl"); FileTemplateLoader ftl1=new FileTemplateLoader(new File("src/ftl")); FileTemplateLoader ftl2=new FileTemplateLoader(new File("src/ftl2")); ClassTemplateLoader ctl=new ClassTemplateLoader(TemplateLoad.class, "../../../ftl3"); TemplateLoader[] loaders={ctl,ftl2}; MultiTemplateLoader mtl=new MultiTemplateLoader(loaders); cfg.setTemplateLoader(mtl); Template template=cfg.getTemplate("ftl2.ftl"); System.out.println(template);
javase項目中使用setDirectoryForTemplateLoading來加載模板所在文件夾,javaee項目中使用setClassForTemplateLoading路徑,servlet中可以使用setServletContextForTemplateLoading來加載模板路徑。
4.3其它配置
配置就是在對象中存儲常用的設置和定義某些想在所有模板中可用的變量,配置對象是freemarker.template.Configuration的實例,可以通過構造方法來創建它。而且一個應用程序通常只使用一個共享的Configuration實例。
設置共享變量:setSharedVariable()
國家地區:setLocale();
數字格式:setNumberFormat("0.##");
通用設置:setSetting(String name, String value)方法
緩存:設置緩存:setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250)) 或setSetting(Configuration.CACHESTORAGEKEY, "strong:20, soft:250");
清空緩存:clearTemplateCache
Configuration cfg=new Configuration(Configuration.VERSION_2_3_22); cfg.setDirectoryForTemplateLoading(new File("src/ftl")); //設置共享便令 cfg.setSharedVariable("site", "Java開發日記"); //設置小數點后保留兩位 cfg.setNumberFormat("0.##");、 //設置緩存,一級緩存20個,2級緩存250個 cfg. setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250)); //cfg.setSetting(Configuration.CACHE_STORAGE_KEY, "strong:20, soft:250"); //cfg.clearTemplateCache(); //清楚緩存 Template template = cfg.getTemplate("config.ftl"); Writer writer = new FileWriter(new File("src/finish/config.html"));
總結:上面這些就是FreeMarker模板引擎的基本操作,首先需要進入jar包,之后設置模板所在的路徑并引入模板,然后組裝數據(實際操作中通過jdbc連接數據庫來操作),所以主要學的就兩方面內容:模板和數據,而模板又與這許許多多的指令相關,所以必須要掌握這些指令。
家好,本篇文章分享企業項目介紹的布局設計,這種樣式設計通常用于企業網站上方的項目介紹或者服務介紹,可以更好的突出企業的核心特點和品牌形象。
話不多說,直接看效果圖:
企業項目介紹的布局樣式
HTML代碼 :
<div class="tpt-list cl"> <div class="tpt-wp cl"> <div class="tpt-md-3"> <div class="a"> <i class="layui-icon"></i> <h3>HTML網頁設計</h3> <p>感謝您使用本套網站內容管理系統,致力于為您創建一個高效簡潔但穩定實用的網站程序。</p> </div> </div> <div class="tpt-md-3"> <div class="a"> <i class="layui-icon"></i> <h3>HTML網頁設計</h3> <p>感謝您使用本套網站內容管理系統,致力于為您創建一個高效簡潔但穩定實用的網站程序。</p> </div> </div> <div class="tpt-md-3"> <div class="a"> <i class="layui-icon"></i> <h3>HTML網頁設計</h3> <p>感謝您使用本套網站內容管理系統,致力于為您創建一個高效簡潔但穩定實用的網站程序。</p> </div> </div> <div class="tpt-md-3"> <div class="a"> <i class="layui-icon"></i> <h3>HTML網頁設計</h3> <p>感謝您使用本套網站內容管理系統,致力于為您創建一個高效簡潔但穩定實用的網站程序。</p> </div> </div> <div class="tpt-md-3"> <div class="a"> <i class="layui-icon"></i> <h3>HTML網頁設計</h3> <p>感謝您使用本套網站內容管理系統,致力于為您創建一個高效簡潔但穩定實用的網站程序。</p> </div> </div> <div class="tpt-md-3"> <div class="a"> <i class="layui-icon"></i> <h3>HTML網頁設計</h3> <p>感謝您使用本套網站內容管理系統,致力于為您創建一個高效簡潔但穩定實用的網站程序。</p> </div> </div> </div> </div>
部分CSS代碼分析:
首先我們給網頁定義一個白色背景
body { background: #fff; }
定義整個布局的寬度為1200像素,并居中顯示
.tpt-wp { width: 1200px; margin: 0 auto }
使布局分成三個相等的寬度,各占百分之三十三點三,并往左浮動
.tpt-md-3 { width: 33.3%; float: left }
給每份布局定義外邊距20像素,內邊距為上下50像素,左右20像素
.tpt-list .a { margin: 20px; padding: 50px 20px; }
給上方的圖標標簽定義一個56像素的大小,顏色為紅色
.tpt-list i { font-size: 56px; color: #ff5722; }
給h3標題定義20像素的大小,黑色的字體顏色,行高為30像素,內邊距為上下10像素
.tpt-list h3 { color: #333; font-size: 20px; line-height: 30px; padding: 10px 0 }
最后給文字介紹14像素的大小,灰色的字體顏色,行高為24像素
.tpt-list p { color: #999; font-size: 14px; line-height: 24px; }
當然,布局的方式有很多種,這只是其中一個方法,也歡迎大家留言分享一下其他的布局方式,點擊下面了解更多獲取全部CSS代碼。
導專家:
謝 晶 上海海洋大學食品學院院長、教授
沈 群 中國農業大學食品科學與營養工程學院教授
黃忠民河南農業大學食品科學技術學院教授
元宵節是中國農歷春節后第一個重要節日,人們在當天有食用元宵(湯圓)的傳統。“包湯圓”和“滾元宵”所用的原料、配料基本相同,但制作工藝略有不同,口感亦有所區別。面對市場上琳瑯滿目的元宵產品,消費者該如何選購呢?國家市場監督管理總局從閱讀元宵包裝食品標簽角度提示如下。
一、標簽信息要齊全,“9+”要素不可缺
消費者在超市等正規食品銷售場所或渠道購買元宵,需仔細查看包裝上食品標簽內容是否齊全。按照國家相關標準要求,直接向消費者提供的預包裝食品標簽標示應包括:食品名稱、配料表、凈含量和規格、生產者和(或)經銷者的名稱、地址和聯系方式、生產日期和保質期、貯存條件、食品生產許可證編號、產品標準代號等9大項目,及其他需要標示的內容。不要購買或食用無標簽或標簽信息不全、內容不清晰,掩蓋、補印或篡改標示的元宵。
二、配料順序有講究,致敏信息勿漏讀
按照有關國家食品安全標準要求,在制造或加工食品時使用的,并存在于產品中的任何物質(包括食品添加劑),都需要在食品配料表中一一標示。加入量超過2%的配料,應按制造或加工食品時加入量從高到低依次排列。因此,消費者在選購元宵時,可以先察看配料表,了解產品的配料使用情況,再決定購買哪種產品。
配料中若含有可能導致過敏的食品及其制品,如含有麩質的谷物及其制品、花生及其制品等,廠家一般會(不是必須)在配料表中使用易辨識的名稱,或在配料表鄰近位置加以提示;加工過程中可能帶入上述食品或其制品,也宜在配料表臨近位置加以提示。因此,易敏人群在挑選或食用元宵時需注意仔細查閱配料表,以及配料表鄰近位置是否有提示信息。
三、兩個日期要細看,貯存烹煮遵說明
產品標簽上的生產日期和保質期要重點查看。選購元宵時,建議購買保質期內的品質穩定產品,不要購買已過保質期的產品。
按照法規要求,在預包裝元宵的標簽上都標示著貯存條件。如速凍湯圓一般要求在-18℃條件下儲存,無論在選購產品時還是購買后,都應確保產品貯存在標簽標示的貯存條件下。
此外,通常在元宵包裝標簽上,廠家一般會給出合理的烹煮建議,消費者可參考以獲得最佳口感。
四、營養標簽細閱讀,參照購買更合適
根據國家相關標準要求,元宵標簽上還會提供營養標簽。營養標簽主要包括:表格形式的“營養成分表”,以及解釋營養成分水平高低的“營養聲稱”和解釋健康作用的“營養成分功能聲稱”。其中,營養成分表至少應標出5個要素(能量、蛋白質、脂肪、碳水化合物、鈉)的含量及其占營養素參考值(NRV)的百分比。消費者可根據營養素參考值和自身狀況選擇食用。
五、元宵味雖美,特殊人群需注意
消費者可根據自己的喜好,按照預包裝上標示的名稱,選購元宵。一般來說,甜味元宵的主要配料包括糯米粉、變性淀粉、白砂糖等。由于糖和油的含量相對較高,建議消費者要適量食用,消化系統相對較弱的老年人和兒童更要注意食用量,糖尿病和心腦血管病等特殊疾病患者謹慎食用。
針對元宵的選購要點、食用建議、儲藏方法等方面提示,已于2018年3月1日在原食品藥品監管總局網站發布的《元宵節飲食安全的消費提示》中,消費者可在此鏈接中查看http://samr.cfda.gov.cn/WS01/CL1680/225704.html。(中國食品科學技術學會提供技術支持)
*請認真填寫需求信息,我們會在24小時內與您取得聯系。