Handlebars庫是另一個模板引擎。他繼承自Mustache,所以大部分語法是兼容Mustance的。但Handlebars也新增了很多特性,比如superset。
在設計上,Handlebars不同於Jade,他不允許在模板裏寫很多JavaScript邏輯,這有助於保持模板的簡潔和嚴格相關的數據表示。
Jade和Handlebars的另一個顯著的不同是,Handlebars要求書寫完整的HTML代碼,正是由於這個原因,他可以不那麼關心空格和縮進。
一、變量
Handlebars的表達式是{{內容}}。
如:
<h1>{{title}}</h1>
<p>{{body}}</p>
對應的數據:
{
title: "Express.js Guide",
body: "The Comprehensive Book on Express.js"
}
渲染後:
<h1>Express.js Guide</h1>
<p>The Comprehensive Book on Express.js</p>
二、each語句
在Handlebars中,each是一個內置的helpers,可以迭代對象和數組。當遍歷的是對象時,在循環體中可以使用@key;
當遍歷的是數組時,在循環體中可以使用@index。另外,this指向每一個循環項item。當item本身是一個對象時,this可以省略,只要寫屬性的名字就可以取到該屬性的值。
如:
<div>
{{#each languages}}
<p>{{@index}}. {{this}}</p>
{{/each}}
</div>
對應的數據:
{languages: ['php', node', 'ruby']}
編譯後輸出的HTML代碼如下:
<div>
<p>0. php</p>
<p>1. node</p>
<p>2. ruby</p>
</div>
三、非轉義輸出
默認情況下,Handlebars會對變量的值進行轉義。如果不想轉義某個值,可以用三個大括號{{{和}}}
如:
{
arr: [
'<a>a</a>',
'<i>italic</i>',
'<strong>bold</strong>'
]
}
模板:
<ul>
{{#each arr}}
<li>
<span>{{@index}}</span>
<span>unescaped: {{{this}}} vs. </span>
<span>escaped: {{this}}</span>
</li>
{{/each}}
</ul>
渲染後:
<ul>
<li>
<span>0</span>
<span>unescaped: <a>a</a> vs. </span>
<span>escaped: <a>a</a></span>
</li>
<li>
<span>1</span>
<span>unescaped: <i>italic</i> vs. </span>
<span>escaped: <i>italic</i></span>
</li>
<li>
<span>2</span>
<span>unescaped: <strong>bold</strong> vs. </span>
<span>escaped: <strong>bold</strong></span>
</li>
</ul>
四、if語句
if是另一個內置的helper,用符號#
如:
{{#if user.admin}}
<button class="launch">Launch Spacecraft</button>
{{else}}
<button class="login">Log in</button>
{{/if}}
數據:
{
user: {
admin: true
}
}
渲染後:
<button class="launch">Launch Spacecraft</button>
五、unless
這個內置的helper與if語句剛好相反。比如,前面的代碼片段可以用unless語句重寫。
{{#unless user.admin}}
<button class="launch">Launch Spacecraft</button>
{{else}}
<button class="login">Log in</button>
{{/unless}}
渲染後:
<button class="login">Log in</button>
六、with
當有很多個有內嵌屬性的對象時,我們可以使用with傳遞上下文。比如,用下面的代碼處理用戶的聯繫方式和地址信息:
{{#with user}}
<p>{{name}}</p>
{{#with contact}}
<span>weibo: @{{weibo}}</span>
{{/with}}
<span>Address: {{address.city}},
{{/with}}
{{user.address.state}}</span>
接着用下面的數據填充模板。注意屬性的名字和Handlebars模板中唯一的user對象的名字是相同的:
{user{
contact: {
email: '[email protected]',
weibo: '深情小建'
},
address: {
city: 'beijin',
state: 'China'
},
name: 'lijian'
}}
渲染後:
<p>lijian</p>
<span>weibo: @深情小建</span>
<span>Address: beijin, China
</span>
七、註釋
想要輸出註釋,可以使用常規的HTML註釋<!---->
.
若要在最終的輸出中隱藏註釋,那就使用{{!}}
,或者{{!----}}
如:
<!--content goes here-->
<p>Node.js is a non-blocking I/O for scalable apps.</p>
{{! @todo change this to a class}}
{{!-- add the example on {{#if}} --}}
<p> id="footer">Copyright 2015 lijian</p>
輸出:
<!-- content goes here -->
<p>Node.js is a non-blocking I/O for scalable apps.</p>
<p> id="footer">Copyright 2015 lijian</p>
八、自定義Helpers
自定義的Handlebars helper和內置的helper塊相似,也和Jade中的mixin相似。想要使用自定義helpers,就需要像創建JavaScript函數那樣去創建他們,並且用Handlebars instance去註冊。
下面的這個Handlebars模板使用了自定義的helper table,我們會在後面的JavaScript/Node.js代碼中註冊table:{{table nod}}
JavaScript/Node.js會告訴Handlebars的編譯器,當遇到自定義的table函數時做什麼
如:
Handlebars.registerHelper('table', function(data){
var str = '<table>';
for (var i=0; i<data.length; i++){
str += '<tr>';
for (var key in data[i]){
str += '<td>' + data[i][key] + '</td>';
};
str += '</tr>';
};
str += '</table>';
return new Handlebars.SafeString(str);
});
table的數據:
{
node:[
{name: 'express', url:'http://expressjs.com/'},
{name: 'hapi', url:'http://spumko.github.io/'},
{name: 'compound', url:'http://compoundjs.com/'},
{name: 'derby', url:'http://derbyjs.com/'}
]
}
生成的HTML輸出:
<table>
<tr>
<td>express</td>
<td>http://expressjs.com/</td>
</tr>
<tr>
<td>hapi</td>
<td>http://spumko.github.io/</td>
</tr>
<tr>
<td>compound</td>
<td>http://compoundjs.com/</td>
</tr>
<tr>
<td>derby</td>
<td>http://derbyjs.com/</td>
</tr>
</table>
九、Include
Handlebars中的Include是由表達式{{>partical_name}}解釋的。包含的子模板和helper類似,
是用Handlebars.registerPartial(name, source)註冊的,其中name是一個字符串,source是待包含的Handlebars子模板