1. 程式人生 > >推薦五款流行的JavaScript模板引擎

推薦五款流行的JavaScript模板引擎

推薦五款流行的JavaScript模板引擎

近日一位20歲的開發者Jack Franklin在《The top 5 JavaScript templating engines》一文中向開發者們推薦了5款流行的JavaScript模板引擎。下面為該文的譯文。

當你建立JavaScript應用時,你必然會用到JavaScript模板。當對HTML進行更新時,你可使用模板來代替庫(如jQuery),使用模板可以大大簡化你的程式碼。該文將例舉當前較流行的一些模板庫。

Mustache通常被稱為JavaScript模板的基礎。另一個流行的解決方案Hanldebars實際上就是基於Mustache構建而成的。這並不意味著

Mustache是一個不好的模板解決方案。下面例舉一例:

1

2

Mustache.render("Hello,  {{name}}", { name: "Jack" });

// 返回: Hello, Jack

一旦在頁面中包含了Mustache,你就可以訪問全域性物件“Mustache”。你可使用其中最主要的方法“render”,它包含兩個引數。首個引數是實際的模板,第二個引數則為需要傳入的引數值。

上例中,你可以看見“{{name}}”。其中的“{{}}”實際上為Mustache的語法,表示一個佔位符。當Mustache對其進行編譯時,它將在傳入的對像中尋找“name”屬性,並用該屬性的值(該例中為

“Jack”)來代替“{{name}}”

在這裡,模板只為一個字串,但如果你有一個更復雜的模板,該方法可能就不適用了。通常的解決方案是將模板放在“script”標籤中:

1

2

3

<script  type="text/x-mustache" id="template">

    <p>Hello,  {{name}}</p>

  </script>

然後,我們可以訪問的script標籤的內容。例如,使用jQuery,它很容易實現:

1

2

3

var temp =  $("#template").html();

Mustache.render(temp {  name: "Jack" });

// 返回: <p>Hello, Jack</p>

“script”一個瀏覽器無法理解的“type”屬性,瀏覽器就會忽略該Script,不將它作為JavaScript,也不會執行它。

你也可在模板中使用迴圈,如下面這個模板:

1

2

3

{{#people}}

  {{name}}

{{/people}}

傳遞資料:

1

{ people: [ {  name: "Jack" }, { name: "Fred" } ] }

你將得到“JackFred”字串。

Mustache還有更多的功能,點選這裡檢視詳情。

Underscore提供了各種各樣的有用的方法,也提供了簡單的模板。它的語法與Mustache稍有不同。下面為一個簡單案例:

1

2

_.template("Hello, <%=  name %>", { name: "Jack" });

 // 返回:Hello, Jack

如果你曾經使用過Embedded Ruby(縮寫為ERB),你就會對該語法更為熟悉。“<%=name%>”表示無論“name”是什麼值,都應該輸出在“<%=name%>”的位置。Underscore同樣有迴圈與條件語句,但與Mustache同樣稍有不同。

1

2

var template  = "<% _.each(people, function(name) { %>  <li><%=   name %></li> <% }); %>"

_.template(template, { people:  ["Jack", "Fred"] } );

Underscore模板中,你可以在“<% %>”是插入任何JavaScript。注意,“<%= %>”用於輸出,<% %>用來包含JavaScript。這意味著你在JS中使用的任何形式的迴圈與條件語句同樣可以在Underscore中使用。

瞭解Underscore更多功能,請點選這裡檢視。

Embedded JSEJS來源於ERB模板,且與ERB有很多相似之處。它有著與ERB相同的Tag,且包含很多相同的功能。

EJS的特別之處在於,你需要把模板存於單獨檔案中,並將檔名傳遞給EJS。它會載入該檔案,並返回HTML

1

2

3

4

5

6

// in template.ejs

  Hello, <%= name  %>

// in JS file

  new EJS({ url: "template.ejs" }).render({ name: "Jack" });

// 返回: Hello, Jack

注意,你可以載入文字模板:

1

new EJS({ text: "Hello,  <%= name %>" }).render({ name: "Jack" });

下面將介紹如何進行迴圈,以陣列“People”為例,並在網站上鍊接到他們的個人頁面:

1

2

3

4

5

6

7

8

9

10

11

12

// template.ejs

  <ul>

    <% for(var i = 0; i < people.length; i++) { %>

      <li><%=  link_to(people[i], "/profiles/" + people[i])  %></li>

    <% }  %>

  </ul>

// in JS file

new EJS({  url: "template.ejs" }).render({ people:  [ "Jack", "Fred" ] })

// Each rendered <li> will  look like:

<li><a  href="/profiles/Jack">Jack</a></li>

這與Underscore 有些相似,但要注意“link_to”的使用。它是EJS定義的一個Helper,以便連結更容易使用。

瞭解更多EJS,請關注EJS官方網站

Handlebars為最流行的模板引擎之一,構建於Mustache之上。適用於Mustache模板的功能同樣適用於Handlebars模板。同時,Handlebars還增加了很多Helper。其中之一是“With”

1

2

3

4

5

// with this template:

  var source = "{{#with author}} <h2>By  {{firstName}} {{lastName}}</h2> {{/with}}";

  var template = Handlebars.compile(source);

  var html = template({ author: {  firstName: "Jack", lastName: "Franklin" } });

// returns: <h2>By Jack  Franklin</h2>

注意,Handlebars編譯器的工作方式略有不同。首先,你把該模板傳遞給“Handlebars.compile”,它會返回一個函式。你將包含資料的物件傳遞給該函式,該函式將返回HTML“{#with}}”Helper取得一個物件,並允許你在其中向該物件傳遞屬性。但不是採用以下形式:

1

{{ author.firstName}}  {{author.lastName}}

而是下面這種形式

1

{{#with author}} {{firstName}} {{lastName}}  {{/with}}

這樣可以節約輸入,尤其當你十分頻繁地使用它時。

Handlebars也提供了“each”Helper

1

2

3

4

var source  = "{{#each people}} {{name}} {{/each}}";

  var template = Handlebars.compile(source);

  var html = template({ people: [{ name: "Jack" }, { name: "Fred" }] });

  //返回: "JackFred"

此外,你還可以使用自己的方法來擴充套件Handlebars,具體方法可參與該文件

隨著Node.js的流行及大量Web應用構建於它之上,現在已有很多模板被設計用於伺服器端。Jade模板與我們目前為止看到的大不相同,它依靠大量的縮排與空格。下面看一例:

1

2

3

4

5

6

7

8

9

10

// template.jade

  p

    | Hello,

    = name

// JS

  jade.renderFile("template.jade",  { name: "Jack" }, function(err, result) {

    console.log(result);

    // logs:  Hello, Jack

  });

首次看到Jade可能會讓你不舒服,但你會很快適應它。在“p”下面縮排兩個字元,表明這兩個字元存在於“p”內。“|”用來告知Jade,該行是需要輸出的純文字;“=”用來告知Jade尋找一個名為“name”的變數。

我們同樣可以在Jade中使用迴圈:

1

2

each person in people

    li=person

調出儲存名字的陣列:{ people: [ "Jack", "Fred" ]},它將輸出:

1

<li>Jack</li><li>Fred</li>

Jade具有很多其他模板所不具有的功能。它也可以做諸如輸出Script標籤此類的事:

1

script(type="text/javascript",  src="myfile.js")

The top 5 JavaScript templating engines

Progressions in applicationdevelopment with JavaScript has led to a number of libraries existing tosupport them. Developer Jack Franklin talks through some of the popular templatinglibraries.

Whenyou build a JavaScript application, you'll almost certainly use some JavaScripttemplates. Rather than use a library like jQuery (or vanilla JavaScript) toupdate your HTML when values update, you can use templates, which cleans upyour code hugely. In this article, we'll look at some popular templatinglibraries.

Mustacheis often considered the base for JavaScript templating

Mustacheisoften considered the base for JavaScript templating. Another popular solution,Handlebars, actually builds on top of Mustache, but that doesn't mean that itisn't a very good templating solution. Here's an example:

Mustache.render("Hello,{{name}}", { name: "Jack" });//returns: Hello, Jack

OnceMustache is included on your page, you have access to the global 'Mustache'object. The main method you'll use is 'render', which takes two arguments. Thefirst is the actual template, and the second is any arguments that need to bepassed to it.

Inthe above example, you can see I've referenced '{{name}}'. Two braces aroundsomething is the Mustache syntax to show that it's a placeholder. When Mustachecompiles it, it will look for the 'name' property in the object we pass in, andreplace '{{name}}' with the value, which is "Jack", in this case.

HereI've passed in the template as a string, but if you had a more complextemplate, you might not like to do it this way. Instead, a common solution isto place a template inside 'script' tags:

<script type="text/x-mustache"id="template">   <p>Hello, {{name}}</p> </script>

Wecan then access the contents of that script tag. For example, with jQuery it'sas easy as:

var temp = $("#template").html(); Mustache.render(temp { name: "Jack" });//returns: <p>Hello, Jack</p>

Bygiving the 'script' tag a 'type' attribute of something the browser doesn'tunderstand, it will ignore the contents, so it doesn't try to execute it asJavaScript.

Youcan also use loops in your templates. Taking this template:

{{#people}}   {{name}} {{/people}}

Withthis data passed in:

{ people: [ { name: "Jack" }, { name: "Fred" }] }

You'llget the string "JackFred" returned.

Mustache is capable of a lot more than coveredhere, so do check the Github READMEformore.

Underscoreis a utlity belt library for JavaScript

Underscoreis a utlity belt library for JavaScript, providing all sorts of useful methods.It also provides simple templates we can use. It uses a slightly differetsyntax to Mustache. Here's a simple example:

_.template("Hello, <%= name %>", { name:"Jack" });//returns: Hello, Jack

Ifyou've ever used Embedded Ruby (or ERB for short), you may be more familiarwith this syntax. The '<%= name %>' denotes that whatever the value of`name` should be outputted in place of '<%= name %>'. Underscore can alsodo things like loops and conditionals, but it does it slightly differently tohow Mustache does.

var template = "<%_.each(people, function(name) { %> <li><%=   name%></li> <% }); %>" _.template(template, { people: ["Jack", "Fred"] } );

InUnderscore templates, you can embed arbitary JavaScript within '<% %>'tags. Note that we use '<%= %>' to output to the page, and `<% %>`to contain JavaScript. This means any form of loop or conditional you can do inJS, you can use in Underscore.

You can find out more about Underscore and itscapabilitieshere.

EmbeddedJS (EJS) is inspired by ERB templates

EmbeddedJS(EJS)is inspired by ERB templates and acts much the same. It uses the same tags asERB (and indeed, Underscore) and has many of the same features. It also implementssome Ruby on Rails inspired helpers, which we'll get to shortly.

EJSis different in that it expects your templates to be in individual files, andyou then pass the filename into EJS. It loads the file in, and then gives youback HTML.

// in template.ejs
 Hello, <%= name %>

// in JS file
 new EJS({ url: "template.ejs" }).render({ name: "Jack" });//returns: Hello, Jack

Notethat you can load in text templates, too:

new EJS({ text: "Hello, <%= name %>" }).render({name: "Jack" });

Here'show we would loop over some people, and link to their profile pages on ourwebsite:

// template.ejs
 <ul>   <% for(var i = 0; i < people.length; i++) { %>     <li><%= link_to(people[i], "/profiles/" + people[i])%></li>   <% } %> </ul>

// in JS file
 new EJS({ url: "template.ejs" }).render({ people: [ "Jack","Fred" ] })

 // Each rendered <li> will looklike:
  
<li><ahref="/profiles/Jack">Jack</a></li>

That's very similar to how Underscore might doit, but note the use of `link_to`. That's a helper that EJS defines to makelinking a little bit easier. It implements a lot of others too, which aredocumented here.To find out more about EJS, I suggest theEJS home page.

Handlebarsis one of the most popular templating engines and builds on top of Mustache

Handlebarsis one of the most popular templating engines and builds on top of Mustache.Anything that was valid in a Mustache template is valid in a Handlebarstemplate, so I won't cover those basics again. Handlebars add lots of helpersto Mustache. One of these is 'with', which is great for working with deepobjects:

// with this template:
  
var source = "{{#withauthor}} <h2>By {{firstName}} {{lastName}}</h2> {{/with}}"; var template = Handlebars.compile(source); var html = template({ author: { firstName: "Jack", lastName:"Franklin" } });//returns: <h2>By Jack Franklin</h2>

Noticethat the Handlebars compiler works slightly differenly. Firstly, you pass thetemplate into 'Handlebars.compile', which then returns a function. You can callthat, passing in the object containing the data, and then you get the HTMLback. The '{{#with}}' helper takes an object and then within it allows you torefer to properties within that object. This means rather than doing:

 {{ author.firstName}} {{author.lastName}}

Wecan do:

 {{#with author}} {{firstName}} {{lastName}} {{/with}}

Whichcan save on typing, especially if you're doing it a lot.

Handlebarsalso provides an each helper:

var source = "{{#each people}} {{name}} {{/each}}"; var template = Handlebars.compile(source); var html = template({ people: [{ name: "Jack" }, { name:"Fred" }] });
  // returns: "JackFred"

Personally for me, I prefer Handlebars andtend to use it for all my client side templating. It's also very easy to extendHandlebars with your own methods - this documentationisa good place to start.

Jadetemplates are very different in that they depend hugely on indents andwhitespace

I'm going to end with something a bitdifferent here - server side templating with Jade.With the popularity of NodeJS and the number of web apps being built in it now,there's a lot of templating libraries out there designed to be used on theserver. Jade templates are very different to any we've looked at so far, inthat it depends hugely on indents and whitespace. Here's a simple example:

// template.jade
 
p   | Hello,   = name

// JS
  
jade.renderFile("template.jade",{ name: "Jack" }, function(err, result) {   console.log(result);   // logs: Hello, Jack });

Jadeis a little jarring to look at at first, but you do get used to it, honest! Weindent the two lines below the 'p' to denote that they exist within it. The '|'is used to tell Jade that what's on that line is just plain text to output, andthe '=' tells Jade to look for a variable named 'name'.

Wecan also do loops in Jade too:

each person in people   li=person

Calledwith an array of names: '{ people: [ "Jack", "Fred" ]}',this will output:

<li>Jack</li><li>Fred</li>

Jadeis capable of a lot more - unlike the other template engines we've looked at,the idea with Jade is that you write the entire of your HTML in it. It can dothings like output script tags:

script(type="text/javascript",src="myfile.js")

A good place to start is the Jade examples.You can download them and run them with Node to see the output and how Jade works.

Andthat concludes our look at five of the most popular templating engines. There'splenty more out there, but hopefully this should give you a good starting pointto go and find the one that suits you best.

Jack Franklin is a 20-year-old developer living in London, UK. Heruns a JavaScript blog atjavascriptplayground.comand also writes PHP, Ruby andother languages. He tweets as@Jack_Franklin.

Also read:

·        Inspiring examples of CSS