Handlebars的基本用法

使用Handlebars,你能夠輕鬆建立語義化模板,Mustache模板和Handlebars是兼容的,因此你能夠將Mustache導入Handlebars以使用 Handlebars 強大的功能。javascript

 

開始

Handlebars模板看起來和HTML同樣,只是嵌入了 handlebars 表達式html

 

  1. <div class="entry">
  2. <h1>{{title}}</h1>
  3. <div class="body">
  4. {{body}}
  5. </div>
  6. </div>

 

handlebars表達式以{{開頭,中間寫一些內容,以}}結尾。java

你可使用<script>標籤引入handlebars模板:express

 

  1. <script id="entry-template" type="text/x-handlebars-template">
  2. template content
  3. </script>

 

在javascript中使用Handlebars.compile編譯模板:瀏覽器

 

  1. var source = $("#entry-template").html();
  2. var template = Handlebars.compile(source);

 

你也能夠預編譯你的模板,而後只需引入更小的運行時庫(handlebars.runtime.js),避免在瀏覽器中編譯,提升性能,這在移動設備中顯得更重要。安全

傳入數據上下文(context),handlebars會執行並生成HTML:less

 

  1. var context = {title: "My New Post", body: "This is my first post!"}
  2. var html = template(context);

 

獲得的結果是:函數

 

  1. <div class="entry">
  2. <h1>My New Post</h1>
  3. <div class="body">
  4. This is my first post!
  5. </div>
  6. </div>

 

HTML編碼

在handlebars裏,{{expression}}會返回一個通過編碼的HTML,若是你不但願被編碼,可使用{{{post

 

  1. <div class="entry">
  2. <h1>{{title}}</h1>
  3. <div class="body">
  4. {{{body}}}
  5. </div>
  6. </div>

 

使用這樣的數據上下文:性能

 

  1. {
  2. title: "All about <p> Tags",
  3. body: "<p>This is a post about &lt;p&gt; tags</p>"
  4. }

 

結果是:

 

  1. <div class="entry">
  2. <h1>All About &lt;p&gt; Tags</h1>
  3. <div class="body">
  4. <p>This is a post about &lt;p&gt; tags</p>
  5. </div>
  6. </div>

 

handlebars不會編碼Handlebars.SafeString。若是你自定義一個helper,返回一段HTML代碼,你須要返回new Handlebars.SafeString(result)。此時,你須要手動對內容進行編碼:

 

  1. Handlebars.registerHelper('link', function(text, url) {
  2. text = Handlebars.Utils.escapeExpression(text);
  3. url = Handlebars.Utils.escapeExpression(url);
  4.  
  5. var result = '<a href="' + url + '">' + text + '</a>';
  6.  
  7. return new Handlebars.SafeString(result);
  8. });

 

這裏將會對傳入的參數進行編碼,返回值是「安全的」,因此就算你不使用{{{,handlebars也不會再次編碼了。

 

塊表達式

塊表達式容許你定義helper,用不一樣的數據上下文(context)調用一段模板。下面咱們定義一個生成列表的helper:

 

  1. {{#list people}}{{firstName}} {{lastName}}{{/list}}

 

若是咱們的數據是這樣的:

 

  1. {
  2. people: [
  3. {firstName: "Yehuda", lastName: "Katz"},
  4. {firstName: "Carl", lastName: "Lerche"},
  5. {firstName: "Alan", lastName: "Johnson"}
  6. ]
  7. }

 

咱們建立一個叫list的helper來生成列表,helper接受people做爲第一個參數,一個option對象(hash)做爲第二個參數。option包含一個屬性fn,他能夠調用一個context就像普通模板同樣。

 

  1. Handlebars.registerHelper('list', function(items, options) {
  2. var out = "<ul>";
  3.  
  4. for(var i=0, l=items.length; i<l; i++) {
  5. out = out + "<li>" + options.fn(items[i]) + "</li>";
  6. }
  7.  
  8. return out + "</ul>";
  9. });

 

執行後,獲得:

 

  1. <ul>
  2. <li>Yehuda Katz</li>
  3. <li>Carl Lerche</li>
  4. <li>Alan Johnson</li>
  5. </ul>

 

塊表達式有不少特性,例如,能夠建立一個else塊(內置的if helper就有else塊)。另外,若是options.fn(context)對內容編碼過了,handlebars就不會helper內容進行編碼了,不然就編碼兩次了。

更多內容:塊表達式

 

Handlebars 路徑

Handlebars支持簡單的路徑

 

  1. <p>{{name}}</p>

 

也支持嵌套路徑,能夠查找下一級的屬性

 

  1. <div class="entry">
  2. <h1>{{title}}</h1>
  3. <h2>By {{author.name}}</h2>
  4.  
  5. <div class="body">
  6. {{body}}
  7. </div>
  8. </div>

 

此模板使用下面的數據:

 

  1. var context = {
  2. title: "My First Blog Post!",
  3. author: {
  4. id: 47,
  5. name: "Yehuda Katz"
  6. },
  7. body: "My first post. Wheeeee!"
  8. };

 

嵌套路徑一樣支持../,

 

  1. <h1>Comments</h1>
  2.  
  3. <div id="comments">
  4. {{#each comments}}
  5. <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
  6. <div>{{body}}</div>
  7. {{/each}}
  8. </div>

 

儘管連接在打印出的時候,是以comments爲上下文的,可是它能夠訪問到上一級的上下文(context)找到permalink。

../引用上一級的做用域,直接看一下上面模板對應的數據就明白了

 

  1. var data = {
  2. permalink:'http://keenwon.com',
  3. comments: [
  4. {id:1,title:'連接1',body:'連接1'},
  5. {id:2,title:'連接2',body:'連接2'}
  6. ]
  7. };

 

Handlebars能夠經過this引用解決helpers和數據命名衝突的問題。

 

  1. <p>{{./name}} or {{this/name}} or {{this.name}}</p>

 

模板註釋 {{! }} or {{!-- --}}

你能夠在 handlebars 里加註釋:

 

  1. <div class="entry">
  2. {{! only output this author names if an author exists }}
  3. {{#if author}}
  4. <h1>{{firstName}} {{lastName}}</h1>
  5. {{/if}}
  6. </div>

 

註釋不會出如今輸出結果裏,若是想要顯示出來,可使用html的註釋(會被執行,而後以註釋的形式顯示,因此若是html註釋內有錯,仍是會報錯)

 

  1. <div class="entry">
  2. {{! 這個註釋不會顯示在輸出結果中 }}
  3. <!-- 會顯示 -->
  4. </div>

 

全部註釋必須包含結束標籤}},多行註釋可使用{{!-- --}}

 

Helpers

Handlebars Helpers能夠讀取到模板中的任何數據上下文,你可使用Handlebars.registerHelper註冊一個helpers。

 

  1. <div class="post">
  2. <h1>By {{fullName author}}</h1>
  3. <div class="body">{{body}}</div>
  4.  
  5. <h1>Comments</h1>
  6.  
  7. {{#each comments}}
  8. <h2>By {{fullName author}}</h2>
  9. <div class="body">{{body}}</div>
  10. {{/each}}
  11. </div>

 

而後使用以下的數據上下文和Helpers:

 

 

  1. var context = {
  2. author: {firstName: "Alan", lastName: "Johnson"},
  3. body: "I Love Handlebars",
  4. comments: [{
  5. author: {firstName: "Yehuda", lastName: "Katz"},
  6. body: "Me too!"
  7. }]
  8. };
  9.  
  10. Handlebars.registerHelper('fullName', function(person) {
  11. return person.firstName + " " + person.lastName;
  12. });

 

結果是:

 

 

  1. <div class="post">
  2. <h1>By Alan Johnson</h1>
  3. <div class="body">I Love Handlebars</div>
  4.  
  5. <h1>Comments</h1>
  6.  
  7. <h2>By Yehuda Katz</h2>
  8. <div class="body">Me Too!</div>
  9. </div>

 

使用this能夠訪問到當前的上下文

 

  1. <ul>
  2. {{#each items}}
  3. <li>{{agree_button}}</li>
  4. {{/each}}
  5. </ul>

 

使用以下的Helpers和數據上下文

 

  1. var context = {
  2. items: [
  3. {name: "Handlebars", emotion: "love"},
  4. {name: "Mustache", emotion: "enjoy"},
  5. {name: "Ember", emotion: "want to learn"}
  6. ]
  7. };
  8.  
  9. Handlebars.registerHelper('agree_button', function() {
  10. return new Handlebars.SafeString(
  11. "<button>I agree. I " + this.emotion + " " + this.name + "</button>"
  12. );
  13. });

 

結果是:

 

  1. <ul>
  2. <li><button>I agree. I love Handlebars</button></li>
  3. <li><button>I agree. I enjoy Mustache</button></li>
  4. <li><button>I agree. I want to learn Ember</button></li>
  5. </ul>

 

若是你的helpers返回一個html片斷,不想被編碼。必須new一個Handlebars.SafeString返回出來。

 

內置的Helpers

The with Block Helper

一般,Handlebars會將數據上下文傳入編譯方法:

 

  1. var source = "<p>{{lastName}}, {{firstName}}</p>";
  2. var template = Handlebars.compile(source);
  3. template({firstName: "Alan", lastName: "Johnson"});

 

結果:

 

  1. <p>Johnson, Alan</p>

 

使用with能夠改變當前的上下文

 

  1. <div class="entry">
  2. <h1>{{title}}</h1>
  3.  
  4. {{#with author}}
  5. <h2>By {{firstName}} {{lastName}}</h2>
  6. {{/with}}
  7. </div>

 

數據上下文以下:

 

  1. {
  2. title: "My first post!",
  3. author: {
  4. firstName: "Charles",
  5. lastName: "Jolley"
  6. }
  7. }

 

結果:

 

  1. <div class="entry">
  2. <h1>My first post!</h1>
  3.  
  4. <h2>By Charles Jolley</h2>
  5. </div>

 

The each block helper

你可使用內置的each helper生成列表,可使用this訪問當前項。

 

  1. <ul class="people_list">
  2. {{#each people}}
  3. <li>{{this}}</li>
  4. {{/each}}
  5. </ul>

 

數據上下文以下:

 

  1. {
  2. people: [
  3. "Yehuda Katz",
  4. "Alan Johnson",
  5. "Charles Jolley"
  6. ]
  7. }

 

結果:

 

  1. <ul class="people_list">
  2. <li>Yehuda Katz</li>
  3. <li>Alan Johnson</li>
  4. <li>Charles Jolley</li>
  5. </ul>

 

你能夠在任何上下文裏,使用this引用當前的上下文

另外,還可使用{{else}}塊,當列表內容爲空的時候會顯示{{else}}的內容

 

  1. {{#each paragraphs}}
  2. <p>{{this}}</p>
  3. {{else}}
  4. <p class="empty">暫無內容</p>
  5. {{/each}}

 

each中循環每一項的時候,可使用{{@index}}獲取當前的序號。

 

  1. {{#each array}}
  2. {{@index}}: {{this}}
  3. {{/each}}

 

對於object,可使用{{key}}獲取當前的key。

 

  1. {{#each object}}
  2. {{@key}}: {{this}}
  3. {{/each}}

 

在迭代的過程當中,可使用@first@last判斷當前的第一步和最後一步,對於object,只有@first可用。

 

The if block helper

可使用if helper有條件的渲染block,若是是falseundefinednull"" 或者 [](a 「falsy」 value),Handlebars不會渲染此block.

 

  1. <div class="entry">
  2. {{#if author}}
  3. <h1>{{firstName}} {{lastName}}</h1>
  4. {{/if}}
  5. </div>

 

若是使用的是空的數據上下文(例如{}),author會返回undefined,結果是:

 

  1. <div class="entry">
  2. </div>

 

當使用塊表達式,可使用{{else}}來指定一個「片斷」,當結果是 falsy value 的時候呈現

 

  1. <div class="entry">
  2. {{#if author}}
  3. <h1>{{firstName}} {{lastName}}</h1>
  4. {{else}}
  5. <h1>Unknown Author</h1>
  6. {{/if}}
  7. </div>

 

The unless block helper

unless的做用和if恰好相反,但表達式返回falsy value的時候渲染block

 

  1. <div class="entry">
  2. {{#unless license}}
  3. <h3 class="warning">WARNING: This entry does not have a license!</h3>
  4. {{/unless}}
  5. </div>

 

若是當前上下文的license返回一個falsy value,Handlebars會輸出警告信息,不然什麼都不輸出。

 

The log block helper

log helper容許執行模板的時候輸出當前上下文的狀態

 

  1. {{log "Look at me!"}}

 

信息傳給Handlebars.logger.log,重寫這個函數能夠實現自定義的log。

相關文章
相關標籤/搜索