1. 程式人生 > >超快的前端模板引擎 artTemplate

超快的前端模板引擎 artTemplate

artTemplate

新一代 javascript 模板引擎

artTemplate 是新一代 javascript 模板引擎,它在 v8 中的渲染效率可接近 javascript 效能極限,在 chrome 下渲染效率測試中分別是知名引擎 Mustache 與 micro tmpl 的 25 、 32 倍(效能測試)。

引擎支援除錯。若渲染中遇到錯誤,偵錯程式可精確定位到產生異常的模板語句,解決前端模板難以除錯的問題(詳情)。

另外,artTemplate 的模板還支援使用自動化工具預編譯,這一切都在 2KB(Gzip) 中實現!

快速上手

編寫模板

使用一個type="text/html"

script標籤存放模板:

<script id="test" type="text/html">
<h1><%=title%></h1>
<ul>
    <%for(i = 0; i < list.length; i ++) {%>
        <li>條目內容 <%=i + 1%> :<%=list[i]%></li>
    <%}%>
</ul>
</script>

模板邏輯語法開始與結束的界定符號為<% 與%>,若<%

後面緊跟=號則輸出變數內容。

渲染模板

template.render(id, data)

var data = {
    title: '標籤',
    list: ['文藝', '部落格', '攝影', '電影', '民謠', '旅行', '吉他']
};
var html = template.render('test', data);
document.getElementById('content').innerHTML = html;

演示

嵌入子模板

<%include(id, [data])%>語句可以嵌入子模板,其中第二個引數是可選的,它預設傳入當前的資料。

<script id="test" type="text/html">
<h1><%=title%></h1>
<%include('list')%>
</script>

<script id="list" type="text/html">
<ul>
    <%for(i = 0; i < list.length; i ++) {%>
        <li>條目內容 <%=i + 1%> :<%=list[i]%></li>
    <%}%>
</ul>
</script>

演示

不轉義HTML

模板引擎預設資料包含的 HTML 字元進行轉義以避免 XSS 漏洞,若不需要轉義的地方可使用==

<script id="test" type="text/html">
<%==value%>
</script>

若需要關閉預設轉義,可以設定template.isEscape = false

演示

在js中存放模板

template.compile([id], source)將返回一個渲染函式。其中 id 引數是可選的,如果使用了 id 引數,可以使用template.render(id, data)渲染模板。

var source =
  '<ul>'
+    '<% for (var i = 0; i < list.length; i ++) { %>'
+        '<li>索引 <%= i + 1 %> :<%= list[i] %></li>'
+    '<% } %>'
+ '</ul>';

var data = {
    list: ['文藝', '部落格', '攝影', '電影', '民謠', '旅行', '吉他']
};

var render = template.compile(source);
var html = render(data);
document.getElementById('content').innerHTML = html;

演示

新增輔助方法

template.helper(name, callback)輔助方法一般用來進行字串替換,如 UBB 替換、髒話替換等。

例如擴充套件一個UBB替換方法:

template.helper('$ubb2html', function (content) {
    return content
    .replace(/\[b\]([^\[]*?)\[\/b\]/igm, '<b>$1</b>')
    .replace(/\[i\]([^\[]*?)\[\/i\]/igm, '<i>$1</i>')
    .replace(/\[u\]([^\[]*?)\[\/u\]/igm, '<u>$1</u>')
    .replace(/\[url=([^\]]*)\]([^\[]*?)\[\/url\]/igm, '<a href="$1">$2</a>')
    .replace(/\[img\]([^\[]*?)\[\/img\]/igm, '<img src="$1" />');
});

在模板中的使用方式:

<%=$ubb2html(content) %>

注意:引擎不會對輔助方法輸出的 HTML 字元進行轉義。

演示

設定界定符

若前端模板語法與後端語法產生衝突,可以修改模板引擎界定符,例如:

template.openTag = "<!--[";
template.closeTag = "]-->";

演示

自定義語法

artTemplate 提供一個語法擴充套件用來簡化模板邏輯語法。語法示例:

{{if admin}}
    <h3>{{title}}</h3>
    <ul>
        {{each list}}
            <li>{{$index + 1}}: {{$value}}</li>
        {{/each}}
    </ul>
{{/if}}

使用幫助

自動化工具

預編譯工具

使用它可以讓前端模版不再受瀏覽器的限制,支援如後端模版一樣按檔案放置、include 語句等特性,可以像後端一樣書寫前端模板!

編譯後的模板不再依賴前端模板引擎與後端,模板可以通過 SeaJS 或 RequireJS 等載入器進行非同步載入,亦能利用它們成熟的打包合併工具進行上線前的優化,如合併與壓縮。

抽取工具

可以把 HTML 中的模板提取出來以便把模板嵌入到 js 檔案中。

與編譯工具不同的是,抽取後的模板仍然依賴引擎執行。

模板編碼規範

1、不能使用 javascript 關鍵字作為模板變數(包括 ECMA5 嚴格模式下新增的關鍵字):

break, case, catch, continue, debugger, default, delete, do, else, false, finally, for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof, var, void, while, with, abstract, boolean, byte, char, class, const, double, enum, export, extends, final, float, goto, implements, import, int, interface, long, native, package, private, protected, public, short, static, super, synchronized, throws, transient, volatile, arguments, let, yield

2、模板執行在沙箱中,內部無法訪問外部變數,除非給模板定義輔助方法。例如:

template.helper('Math', Math)

模板中若任意引用外部物件,複雜的依賴管理將會讓專案難以維護,這種方式將利於後續模板遷移(包括通過工具預編譯)。

更新記錄

v2.0.2

  1. 優化自定義語法擴充套件,減少體積
  2. [重要]為了最大化相容第三方庫,自定義語法擴充套件預設界定符修改為{{}}
  3. 修復合併工具的BUG #25
  4. 公開了內部快取,可以通過template.cache訪問到編譯後的函式
  5. 公開了輔助方法快取,可以通過template.helpers訪問到
  6. 優化了除錯資訊

v2.0.1

  1. 修復模板變數靜態分析的BUG

v2.0 release

v2.0 beta5

  1. 修復編譯工具可能存在重複依賴的問題。感謝 @warmhug
  2. 修復include內部實現可能產生上下文不一致的問題。感謝 @warmhug
  3. 支援使用拖拽檔案到compile.cmd圖示上進行單獨編譯

v2.0 beta4

  1. 修復編譯工具在壓縮模板可能導致 HTML 意外截斷的問題。感謝 @warmhug
  2. 完善編譯工具對include支援支援,可以支援不同目錄之間模板巢狀
  3. 修復編譯工具沒能正確處理自定義語法外掛的輔助方法

v2.0 beta1

  1. 對非String、Number型別的資料不輸出,而Function型別求值後輸出。
  2. 預設對html進行轉義輸出,原文輸出可使用<%==value%>,也可以關閉預設的轉義功能template.isEscape = false
  3. 增加批處理工具支援把模板編譯成不依賴模板引擎的 js 檔案,可通過 RequireJS、SeaJS 等模組載入器進行非同步載入。