本文翻譯和整理自Handlebars Github和官網(wǎng),當(dāng)前handlebar版本1.3.0。
介紹
Handlebars是一個Javascript模板引擎,能讓你輕松高效的編寫語義化模板,它是Mustache模板引擎的一個擴(kuò)展,Handlebars和Mustache都是弱邏輯的模板引擎,能將Web前端的視圖和代碼分離,降低兩者之間耦合。
Handlebars的特點是一切都是表達(dá)式,沒有data api,不污染HTML標(biāo)簽,和DeDecms、wordpress模板類似,因此能很方便的與其他前端JS庫混用,并且編寫簡單,易于擴(kuò)展。
Handlebars支持的瀏覽器及運(yùn)行環(huán)境有:IE6+、Chrome、Firefox、Safari5+、Opera11+以及Node.js。
Handlebars是ember.js的默認(rèn)模板引擎,同時也是nodejs web框架Clouda、Meteor的默認(rèn)模板引擎。
安裝
Handlebars的安裝很簡單,你可以從 Github和官網(wǎng) 下載最新版本,也可以從bower包管理器中將它添加到你的頁面上。
用法
簡單來說,Handlebars里的語法是Mustache的超集,如果你想了解基礎(chǔ)的語法,可以查看Mustache的幫助頁面,下面也將講解Handlebars中的語法。
基礎(chǔ)語法
Handlebars模板看起來和一般的HTML沒什么兩樣,只不過是在HTML中嵌入了Handlebars的表達(dá)式。如下:
- <div class="entry">
- <h1>{{title}}</h1>
- <div class="body">
- {{body}}
- </div>
- </div>
一個Handlebars的表達(dá)式是被{{ 和}} 包含起來的內(nèi)容。了解更多Handlebars表達(dá)式。
你可以將模板的內(nèi)容或數(shù)據(jù)放到一個<script>標(biāo)簽里,也可以直接寫在javascript里:
- <script id="entry-template" type="text/x-handlebars-template">
- template content
- </script>
當(dāng)你寫了一個模板以后,使用Handlebars.compile 方法將模板編譯為函數(shù),生成的執(zhí)行函數(shù)接受context作為參數(shù),用來渲染模板。了解更多執(zhí)行函數(shù)。
比如下面:
- var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
- "{{kids.length}} kids:</p>" +
- "<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
- var template = Handlebars.compile(source);
-
- var data = { "name": "Alan", "hometown": "Somewhere, TX",
- "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
- var result = template(data);
-
- // 將被渲染為:
- // <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
- // <ul>
- // <li>Jimmy is 12</li>
- // <li>Sally is 4</li>
- // </ul>
你還可以預(yù)編譯你的模板,它將會生成一個小一些的運(yùn)行庫,這對移動設(shè)備上的web頁面非常重要。了解更多預(yù)編譯。
HTML轉(zhuǎn)義
為安全起見,Handlebars表達(dá)式中的一些HTML字符將被轉(zhuǎn)義,如果你不想讓Handlebars轉(zhuǎn)義字符,使用三個花括號{{{ :
- //template:
-
- <div class="entry">
- <h1>{{title}}</h1>
- <div class="body">
- {{{body}}}
- </div>
- </div>
-
- //context:
-
- {
- title: "All about <p> Tags",
- body: "<p>This is a post about <p> tags</p>"
- }
-
- //results:
-
- <div class="entry">
- <h1>All About <p> Tags</h1>
- <div class="body">
- <p>This is a post about <p> tags</p>
- </div>
- </div>
Handlebars不會轉(zhuǎn)義Handlebars.SafeString,如果你想寫一個輸出自身HTML的helper,你可以使用這個方法,用來手動的輸出需要轉(zhuǎn)義的參數(shù)。
- Handlebars.registerHelper('link', function(text, url) {
- text = Handlebars.Utils.escapeExpression(text);
- url = Handlebars.Utils.escapeExpression(url);
-
- var result = '<a href="' + url + '">' + text + '</a>';
-
- return new Handlebars.SafeString(result);
- });
塊級表達(dá)式
塊級表達(dá)式能讓你定義塊級helpers,它能調(diào)用模板的一部分,并且使用與當(dāng)前不同的上下文。下面以一個輸出HTML列表的helper為例:
{{#list people}}{{firstName}} {{lastName}}{{/list}}
定義如下的上下文:
- {
- people: [
- {firstName: "Yehuda", lastName: "Katz"},
- {firstName: "Carl", lastName: "Lerche"},
- {firstName: "Alan", lastName: "Johnson"}
- ]
- }
我們可以創(chuàng)建一個名為list的helper來生成HTML列表,這個helper接受people和options參數(shù),options包含fn屬性,可以調(diào)用上下文。
- Handlebars.registerHelper('list', function(items, options) {
- var out = "<ul>";
-
- for(var i=0, l=items.length; i<l; i++) {
- out = out + "<li>" + options.fn(items[i]) + "</li>";
- }
-
- return out + "</ul>";
- });
執(zhí)行后,生成:
- <ul>
- <li>Yehuda Katz</li>
- <li>Carl Lerche</li>
- <li>Alan Johnson</li>
- </ul>
塊級helper包含更多的特性,如創(chuàng)建一個else 部分(在內(nèi)建的if helper里有用到)。
當(dāng)調(diào)用options.fn(context) 時內(nèi)部的內(nèi)容已經(jīng)被轉(zhuǎn)義,因此Handlebars不會轉(zhuǎn)義塊級helper的結(jié)果,否則會出現(xiàn)兩次轉(zhuǎn)義。了解更多塊級helper。
Handlebars路徑
和Mustache一樣,Handlebars支持簡單的路徑。
Handlebars還支持嵌套的路徑,可以在當(dāng)前上下文中尋找嵌套的屬性。
- <div class="entry">
- <h1>{{title}}</h1>
- <h2>By {{author.name}}</h2>
-
- <div class="body">
- {{body}}
- </div>
- </div>
其對應(yīng)的上下文如下:
- var context = {
- title: "My First Blog Post!",
- author: {
- id: 47,
- name: "Yehuda Katz"
- },
- body: "My first post. Wheeeee!"
- };
因此Handlebars模板能支持更多原始的JSON對象。
嵌套的handlebars路徑可以包含../ 字符段,可以將路徑定位到父級上下文中。
- <h1>Comments</h1>
-
- <div id="comments">
- {{#each comments}}
- <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
- <div>{{body}}</div>
- {{/each}}
- </div>
在這個例子中,post是comments的父級上下文,雖然a標(biāo)簽處于comments的上下文里,但permalink可以上溯到post上下文中。
更嚴(yán)密的講,../ 路徑指的是父級模板的作用域,而不是高一級的上下文,這是因為塊級helper能調(diào)用任何上下文,所以“上一級”的概念在這里并不適合。
模板注釋
在handlebars中使用{{! }} 或者{{!-- --}} 來包含注釋。
- <div class="entry">
- {{! only output this author names if an author exists }}
- {{#if author}}
- <h1>{{firstName}} {{lastName}}</h1>
- {{/if}}
- </div>
Helpers(輔助方法)
Helpers是Handlebars中最重要的概念,它能大大擴(kuò)展Handlebars的使用范圍,Helper自定義函數(shù)的形式將所需要的功能注冊為表達(dá)式,然后可以在Handlebars中使用。
Handlebars提供了Handlebars.registerHelper 方法來自定義Helper,同時也提供了一些常用的內(nèi)建Helper。
比如有如下模板:
- <div class="post">
- <h1>By {{fullName author}}</h1>
- <div class="body">{{body}}</div>
-
- <h1>Comments</h1>
-
- {{#each comments}}
- <h2>By {{fullName author}}</h2>
- <div class="body">{{body}}</div>
- {{/each}}
- </div>
其中上下文和helper如下:
- var context = {
- author: {firstName: "Alan", lastName: "Johnson"},
- body: "I Love Handlebars",
- comments: [{
- author: {firstName: "Yehuda", lastName: "Katz"},
- body: "Me too!"
- }]
- };
-
- Handlebars.registerHelper('fullName', function(person) {
- return person.firstName + " " + person.lastName;
- });
運(yùn)行結(jié)果:
- <div class="post">
- <h1>By Alan Johnson</h1>
- <div class="body">I Love Handlebars</div>
-
- <h1>Comments</h1>
-
- <h2>By Yehuda Katz</h2>
- <div class="body">Me Too!</div>
- </div>
Helpers還可以接受塊級元素當(dāng)前的上下文,就像函數(shù)中的this上下文一樣。
- <ul>
- {{#each items}}
- <li>{{agree_button}}</li>
- {{/each}}
- </ul>
上下文及helper如下:
- var context = {
- items: [
- {name: "Handlebars", emotion: "love"},
- {name: "Mustache", emotion: "enjoy"},
- {name: "Ember", emotion: "want to learn"}
- ]
- };
-
- Handlebars.registerHelper('agree_button', function() {
- return new Handlebars.SafeString(
- "<button>I agree. I " + this.emotion + " " + this.name + "</button>"
- );
- });
運(yùn)行結(jié)果:
- <ul>
- <li><button>I agree. I love Handlebars</button></li>
- <li><button>I agree. I enjoy Mustache</button></li>
- <li><button>I agree. I want to learn Ember</button></li>
- </ul>
內(nèi)建Helpers
Handlebars提供了一系列的內(nèi)建Helper供直接調(diào)用。
with:切換上下文
each:循環(huán)輸出上下文中的內(nèi)容,用this表達(dá)式指代單條內(nèi)容,else表達(dá)式當(dāng)上下文為空時激活
if:條件表達(dá)式
unless:與if表達(dá)式功能相反
log:輸出log本文翻譯和整理自Handlebars Github和官網(wǎng),當(dāng)前handlebar版本1.3.0。
介紹
Handlebars是一個Javascript模板引擎,能讓你輕松高效的編寫語義化模板,它是Mustache模板引擎的一個擴(kuò)展,Handlebars和Mustache都是弱邏輯的模板引擎,能將Web前端的視圖和代碼分離,降低兩者之間耦合。
Handlebars的特點是一切都是表達(dá)式,沒有data api,不污染HTML標(biāo)簽,和DeDecms、wordpress模板類似,因此能很方便的與其他前端JS庫混用,并且編寫簡單,易于擴(kuò)展。
Handlebars支持的瀏覽器及運(yùn)行環(huán)境有:IE6+、Chrome、Firefox、Safari5+、Opera11+以及Node.js。
Handlebars是ember.js的默認(rèn)模板引擎,同時也是nodejs web框架Clouda、Meteor的默認(rèn)模板引擎。
安裝
Handlebars的安裝很簡單,你可以從 Github和官網(wǎng) 下載最新版本,也可以從bower包管理器中將它添加到你的頁面上。
用法
簡單來說,Handlebars里的語法是Mustache的超集,如果你想了解基礎(chǔ)的語法,可以查看Mustache的幫助頁面,下面也將講解Handlebars中的語法。
基礎(chǔ)語法
Handlebars模板看起來和一般的HTML沒什么兩樣,只不過是在HTML中嵌入了Handlebars的表達(dá)式。如下:
- <div class="entry">
- <h1>{{title}}</h1>
- <div class="body">
- {{body}}
- </div>
- </div>
一個Handlebars的表達(dá)式是被{{ 和}} 包含起來的內(nèi)容。了解更多Handlebars表達(dá)式。
你可以將模板的內(nèi)容或數(shù)據(jù)放到一個<script>標(biāo)簽里,也可以直接寫在javascript里:
- <script id="entry-template" type="text/x-handlebars-template">
- template content
- </script>
當(dāng)你寫了一個模板以后,使用Handlebars.compile 方法將模板編譯為函數(shù),生成的執(zhí)行函數(shù)接受context作為參數(shù),用來渲染模板。了解更多執(zhí)行函數(shù)。
比如下面:
- var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
- "{{kids.length}} kids:</p>" +
- "<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
- var template = Handlebars.compile(source);
-
- var data = { "name": "Alan", "hometown": "Somewhere, TX",
- "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
- var result = template(data);
-
- // 將被渲染為:
- // <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
- // <ul>
- // <li>Jimmy is 12</li>
- // <li>Sally is 4</li>
- // </ul>
你還可以預(yù)編譯你的模板,它將會生成一個小一些的運(yùn)行庫,這對移動設(shè)備上的web頁面非常重要。了解更多預(yù)編譯。
HTML轉(zhuǎn)義
為安全起見,Handlebars表達(dá)式中的一些HTML字符將被轉(zhuǎn)義,如果你不想讓Handlebars轉(zhuǎn)義字符,使用三個花括號{{{ :
- //template:
-
- <div class="entry">
- <h1>{{title}}</h1>
- <div class="body">
- {{{body}}}
- </div>
- </div>
-
- //context:
-
- {
- title: "All about <p> Tags",
- body: "<p>This is a post about <p> tags</p>"
- }
-
- //results:
-
- <div class="entry">
- <h1>All About <p> Tags</h1>
- <div class="body">
- <p>This is a post about <p> tags</p>
- </div>
- </div>
Handlebars不會轉(zhuǎn)義Handlebars.SafeString,如果你想寫一個輸出自身HTML的helper,你可以使用這個方法,用來手動的輸出需要轉(zhuǎn)義的參數(shù)。
- Handlebars.registerHelper('link', function(text, url) {
- text = Handlebars.Utils.escapeExpression(text);
- url = Handlebars.Utils.escapeExpression(url);
-
- var result = '<a href="' + url + '">' + text + '</a>';
-
- return new Handlebars.SafeString(result);
- });
塊級表達(dá)式
塊級表達(dá)式能讓你定義塊級helpers,它能調(diào)用模板的一部分,并且使用與當(dāng)前不同的上下文。下面以一個輸出HTML列表的helper為例:
{{#list people}}{{firstName}} {{lastName}}{{/list}}
定義如下的上下文:
- {
- people: [
- {firstName: "Yehuda", lastName: "Katz"},
- {firstName: "Carl", lastName: "Lerche"},
- {firstName: "Alan", lastName: "Johnson"}
- ]
- }
我們可以創(chuàng)建一個名為list的helper來生成HTML列表,這個helper接受people和options參數(shù),options包含fn屬性,可以調(diào)用上下文。
- Handlebars.registerHelper('list', function(items, options) {
- var out = "<ul>";
-
- for(var i=0, l=items.length; i<l; i++) {
- out = out + "<li>" + options.fn(items[i]) + "</li>";
- }
-
- return out + "</ul>";
- });
執(zhí)行后,生成:
- <ul>
- <li>Yehuda Katz</li>
- <li>Carl Lerche</li>
- <li>Alan Johnson</li>
- </ul>
塊級helper包含更多的特性,如創(chuàng)建一個else 部分(在內(nèi)建的if helper里有用到)。
當(dāng)調(diào)用options.fn(context) 時內(nèi)部的內(nèi)容已經(jīng)被轉(zhuǎn)義,因此Handlebars不會轉(zhuǎn)義塊級helper的結(jié)果,否則會出現(xiàn)兩次轉(zhuǎn)義。了解更多塊級helper。
Handlebars路徑
和Mustache一樣,Handlebars支持簡單的路徑。
Handlebars還支持嵌套的路徑,可以在當(dāng)前上下文中尋找嵌套的屬性。
- <div class="entry">
- <h1>{{title}}</h1>
- <h2>By {{author.name}}</h2>
-
- <div class="body">
- {{body}}
- </div>
- </div>
其對應(yīng)的上下文如下:
- var context = {
- title: "My First Blog Post!",
- author: {
- id: 47,
- name: "Yehuda Katz"
- },
- body: "My first post. Wheeeee!"
- };
因此Handlebars模板能支持更多原始的JSON對象。
嵌套的handlebars路徑可以包含../ 字符段,可以將路徑定位到父級上下文中。
- <h1>Comments</h1>
-
- <div id="comments">
- {{#each comments}}
- <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
- <div>{{body}}</div>
- {{/each}}
- </div>
在這個例子中,post是comments的父級上下文,雖然a標(biāo)簽處于comments的上下文里,但permalink可以上溯到post上下文中。
更嚴(yán)密的講,../ 路徑指的是父級模板的作用域,而不是高一級的上下文,這是因為塊級helper能調(diào)用任何上下文,所以“上一級”的概念在這里并不適合。
模板注釋
在handlebars中使用{{! }} 或者{{!-- --}} 來包含注釋。
- <div class="entry">
- {{! only output this author names if an author exists }}
- {{#if author}}
- <h1>{{firstName}} {{lastName}}</h1>
- {{/if}}
- </div>
Helpers(輔助方法)
Helpers是Handlebars中最重要的概念,它能大大擴(kuò)展Handlebars的使用范圍,Helper自定義函數(shù)的形式將所需要的功能注冊為表達(dá)式,然后可以在Handlebars中使用。
Handlebars提供了Handlebars.registerHelper 方法來自定義Helper,同時也提供了一些常用的內(nèi)建Helper。
比如有如下模板:
- <div class="post">
- <h1>By {{fullName author}}</h1>
- <div class="body">{{body}}</div>
-
- <h1>Comments</h1>
-
- {{#each comments}}
- <h2>By {{fullName author}}</h2>
- <div class="body">{{body}}</div>
- {{/each}}
- </div>
其中上下文和helper如下:
- var context = {
- author: {firstName: "Alan", lastName: "Johnson"},
- body: "I Love Handlebars",
- comments: [{
- author: {firstName: "Yehuda", lastName: "Katz"},
- body: "Me too!"
- }]
- };
-
- Handlebars.registerHelper('fullName', function(person) {
- return person.firstName + " " + person.lastName;
- });
運(yùn)行結(jié)果:
- <div class="post">
- <h1>By Alan Johnson</h1>
- <div class="body">I Love Handlebars</div>
-
- <h1>Comments</h1>
-
- <h2>By Yehuda Katz</h2>
- <div class="body">Me Too!</div>
- </div>
Helpers還可以接受塊級元素當(dāng)前的上下文,就像函數(shù)中的this上下文一樣。
- <ul>
- {{#each items}}
- <li>{{agree_button}}</li>
- {{/each}}
- </ul>
上下文及helper如下:
- var context = {
- items: [
- {name: "Handlebars", emotion: "love"},
- {name: "Mustache", emotion: "enjoy"},
- {name: "Ember", emotion: "want to learn"}
- ]
- };
-
- Handlebars.registerHelper('agree_button', function() {
- return new Handlebars.SafeString(
- "<button>I agree. I " + this.emotion + " " + this.name + "</button>"
- );
- });
運(yùn)行結(jié)果:
- <ul>
- <li><button>I agree. I love Handlebars</button></li>
- <li><button>I agree. I enjoy Mustache</button></li>
- <li><button>I agree. I want to learn Ember</button></li>
- </ul>
內(nèi)建Helpers
Handlebars提供了一系列的內(nèi)建Helper供直接調(diào)用。
with:切換上下文
each:循環(huán)輸出上下文中的內(nèi)容,用this表達(dá)式指代單條內(nèi)容,else表達(dá)式當(dāng)上下文為空時激活
if:條件表達(dá)式
unless:與if表達(dá)式功能相反
log:輸出log
|