Jade模板引擎入門教程

Jade是一款高性能簡潔易懂的模板引擎,Jade是Haml的Javascript實現,在服務端(NodeJS)及客戶端均有支持。

功能

  • 客戶端支持
  • 超強的可讀性
  • 靈活易用的縮進
  • 塊擴展
  • 代碼默認通過編碼處理以加強安全性
  • 編譯及運行時的上下文錯誤報告
  • 命令行編譯支持
  • HTML5模式(使用!!!5文檔類型)
  • 可選的內存緩存
  • 聯合動態和靜態標記類
  • 利用過濾器解析樹的處理
  • 支持 Express JS
  • 利用each透明的循環objects,arrays甚至不可枚舉對象
  • 塊註釋
  • 不須要標記前綴
  • AST過濾器
  • 過濾器
  • Vim語法文件
  • TextMate包
  • Screencasts

其它語言實現

安裝

經過npm:php

1
2
<span style="font-size: 13px;">npm install jade
</span>

瀏覽器支持

能夠經過下面命令將jade編譯爲客戶端瀏覽器兼容的文件:css

1
2
<span style="font-size: 13px;">$ make jade.js
</span>

或者,若是你已經經過npm安裝了uglifyjs(npminstalluglify-js),能夠經過下面的命令同時建立兩個文件:html

1
2
<span style="font-size: 13px;">$ make jade.min.js
</span>

公開API

var jade = require('jade');

// 渲染字符串
jade.render('.csser.com 字符串', { options: 'here' });

// 渲染文件
jade.renderFile('path/to/csser.com.jade', { options: 'here' }, function(err, html){
   // 這裏的options是可選的
   // 回調函數能夠做爲第二個參數
});

// 編譯一個函數
var fn = jade.compile('string of jade', options);
fn.call(scope, locals);

Options

  • 執行做用域(this)scope
  • 本地變量對象locals
  • 處理異常及緩存時使用filename
  • 經過文件名將Javascript緩存在內存中cache
  • 輸出生成的標記和函數體debug
  • 替換jade默認編譯引擎compiler

語法

行尾

在解析前會將 CRLF 和 CR 轉換爲 LF.前端

標記

標記是一行的第一個單詞:node

1
2
<span style="font-size: 13px;">html
</span>

會被轉換爲 <html></html>git

標記也能夠有id:github

1
2
<span style="font-size: 13px;">div#container
</span>

這將被渲染成<div id=」container」></div>express

如何處理類?npm

1
2
<span style="font-size: 13px;">div.user-details
</span>

渲染爲: <div class=」user-details」></div>vim

多個class?而且還有id?

1
2
<span style="font-size: 13px;">div#foo.bar.baz
</span>

渲染爲:<div id=」foo」 class=」bar baz」></div>

總寫div確實很煩人,能夠省略之:

1
2
3
<span style="font-size: 13px;">#foo
.bar
</span>

輸出: <div id=」foo」></div><div class=」bar」></div>

標記文本

只須要將文本內容放在標記後面:

1
2
<span style="font-size: 13px;">p wahoo!
</span>

渲染爲 <p>wahoo!</p>.

酷,可是如何處理大段文本呢?

1
2
3
4
5
6
<span style="font-size: 13px;">p
   | foo bar baz
   | rawr rawr
   | super cool
   | go jade go
</span>

渲染爲 <p>foo bar baz rawr…..</p>

內插法?是的,這兩種類型的文本均可以使用內插法,若是咱們傳入{ locals: { name: ‘一回’, email: ‘xianlihua[at]gmail.com’ }},能夠這樣作:

1
2
<span style="font-size: 13px;">#user #{name} &lt;#{email}&gt;
</span>

輸出:<div id=」user」>一回 &lt;xianlihua[at]gmail.com&gt;</div>

出於某種緣由須要輸出#{}?轉義之:

1
2
<span style="font-size: 13px;">p \#{CSSer, 關注Javascript技術}
</span>

這樣就獲得了:<p>#{CSSer, 關注Javascript技術}</p>

也可使用反轉義變量!{html},下面的代碼將輸出script標記:

1
2
3
<span style="font-size: 13px;">- var html = "<script></script>"
| !{html}
</span>

包含文本的嵌套標記也可使用文本塊:

1
2
3
4
<span style="font-size: 13px;">label
   | Username:
   input(name='user[name]')
</span>

或者直接使用標記文本:

1
2
3
<span style="font-size: 13px;">label Username:
   input(name='user[name]')
</span>

只接受純文本的標記,如script,style,以及textarea不須要開頭的|字符,例如:

1
2
3
4
5
6
7
8
9
10
<span style="font-size: 13px;">  html
     head
       title CSSer, 關注Web前端技術
       script
         if (foo) {
           bar();
         } else {
           baz();
         }
</span>

再次做爲替代方案,咱們可使用點號’.'來表示一個文本塊,例如:

1
2
3
4
5
6
7
<span style="font-size: 13px;">  p.
     foo asdf
     asdf
      asdfasdfaf
      asdf
     asd.
</span>

輸出:

1
2
3
4
5
6
7
8
<span style="font-size: 13px;">    <p>foo asdf
     asdf
       asdfasdfaf
       asdf
     asd
     .
     </p>
</span>

若是點號’.'與標記之間有空格,Jade解析其會忽略它,將其做爲文本處理:

1
2
<span style="font-size: 13px;">p .
</span>

輸出:

1
2
<span style="font-size: 13px;"><p>.</p>
</span>

註釋

單行註釋當前看起來與Javascript一致,即「//」,單行註釋的內容必須放在同一行上:

1
2
3
4
<span style="font-size: 13px;">// 一些段落
p foo
p bar
</span>

將會輸出:

1
2
3
4
<span style="font-size: 13px;"><!-- 一些段落 -->
<p>foo</p>
<p>bar</p>
</span>

Jade也支持非緩衝註釋,只需增長一個橫槓:

1
2
3
4
<span style="font-size: 13px;">//- 該行註釋將不會被輸出到解析後的頁面中
p foo
p bar
</span>

輸出:

1
2
3
<span style="font-size: 13px;"><p>foo</p>
<p>bar</p>
</span>

塊註釋

塊註釋會依據縮進進行處理:

1
2
3
4
5
<span style="font-size: 13px;">  body
     //
       #content
         h1 CSSer,關注Web前端技術
</span>

輸出:

1
2
3
4
5
6
7
8
<span style="font-size: 13px;"><body>
   <!--
   <div id="content">
     <h1>CSSer,關注Web前端技術</h1>
   </div>
   -->
</body>
</span>

Jade也支持條件註釋,例如:

1
2
3
4
<span style="font-size: 13px;">body
   /if IE
     a(href='http://www.mozilla.com/en-US/firefox/') Get Firefox
</span>

輸出:

1
2
3
4
5
6
<span style="font-size: 13px;"><body>
   <!--[if IE]>
     <a href="http://www.mozilla.com/en-US/firefox/">Get Firefox</a>
   <![endif]-->
</body>
</span>

嵌套

Jade支持經過嵌套來以天然的方式定義標記:

1
2
3
4
5
6
7
8
<span style="font-size: 13px;">ul
   li.first
     a(href='#') foo
   li
     a(href='#') bar
   li.last
     a(href='#') baz
</span>

塊擴展

塊擴展容許建立單行的簡潔嵌套標記,下面的示例與上例輸出相同:

1
2
3
4
5
<span style="font-size: 13px;">  ul
     li.first: a(href='#') foo
     li: a(href='#') bar
     li.last: a(href='#') baz
</span>

特性

目前Jade支持’(‘和’)'的特性定界符。

1
2
<span style="font-size: 13px;">a(href='/login', title='View login page') Login
</span>

另外咱們也可使用冒號(:)來做爲分割符:

1
2
<span style="font-size: 13px;">a(href: '/login', title: '註冊成爲CSSer.com會員') Login
</span>

Boolean特性也被支持:

1
2
<span style="font-size: 13px;">input(type="checkbox", checked)
</span>

值爲變量的Boolean特性只有在值爲true時輸出:

1
2
<span style="font-size: 13px;">input(type="checkbox", checked: someValue)
</span>

分拆在多行也能正常解析:

1
2
3
4
<span style="font-size: 13px;">input(type='checkbox',
   name='agreement',
   checked)
</span>

文檔類型

利用!!!來增長頁面的文檔類型:

1
2
<span style="font-size: 13px;">!!!
</span>

將會輸出過渡型文檔類型,然而:

1
2
<span style="font-size: 13px;">!!! 5
</span>

將會輸出HTML5的文檔類型,下面是默認定義的文檔類型,這也能夠很容易的被擴展:

var doctypes = exports.doctypes = {
   '5': '<!DOCTYPE html>',
   'xml': '<?xml version="1.0" encoding="utf-8" ?>',
   'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
   'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
   'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
   'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
   '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
   'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
   'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
};

要修改默認值只需改變:

1
2
<span style="font-size: 13px;">jade.doctypes.default = 'whatever you want';
</span>

過濾器

過濾器以冒號(:)做爲前綴,如 :markdown 將會對文本進行函數處理,(一回注:相似Smarty的變量調節器),本頁開始處列出了目前Jade支持的過濾器。

1
2
3
4
5
<span style="font-size: 13px;">body
   :markdown
     Woah! jade _and_ markdown, very **cool**
     we can even link to [CSSer](http://www.csser.com)
</span>

渲染後:

1
2
<span style="font-size: 13px;">   <body><p>Woah! jade <em>and</em> markdown, very <strong>cool</strong> we can even link to <a href="http://www.csser.com">CSSer</a></p></body>
</span>

過濾器也能夠處理解析樹,一般過濾器能夠正常處理文本塊,可是經過傳入規則的塊過濾器能夠作任何它能作的。

1
2
3
4
5
6
7
<span style="font-size: 13px;">body
   conditionals:
     if role == 'admin'
       p You are amazing
     else
       p Not so amazing
</span>

代碼

Jade目前支持三種類型的可執行代碼,第一種以-爲前綴,不會被緩衝:

1
2
<span style="font-size: 13px;">- var foo = 'bar';
</span>

這可被用於條件或循環:

1
2
3
<span style="font-size: 13px;">- for (var key in obj)
   p= obj[key]
</span>

因爲Jade的緩衝技術,下面的代碼是有效的:

1
2
3
4
5
6
7
8
<span style="font-size: 13px;">- if (foo)
   ul
     li yay
     li foo
     li worked
- else
   p oh no! you are not in csser.com
</span>

甚至詳細的迭代循環:

1
2
3
4
5
6
<span style="font-size: 13px;">- if (items.length)
   ul
     - items.forEach(function(item){
       li= item
     - })
</span>

任何你但願的均可以實現!

接下來咱們轉義了緩衝代碼,用於緩衝返回值,以等號(=)做爲前綴:

1
2
3
4
<span style="font-size: 13px;">- var foo = 'bar'
= foo
h1= foo
</span>

輸出: bar<h1>bar</h1>. 被’='緩衝的代碼會默認通過轉義以加強安全性,要輸出爲轉義的值須要使用 !=:

1
2
<span style="font-size: 13px;">p!= aVarContainingMoreHTML
</span>

一個容許使用」vanilla」Javascript的例外,是 – each 標記,其表現形式爲:

1
2
<span style="font-size: 13px;">- each VAL[, KEY] in OBJ
</span>

實現循環數組的例子:

1
2
3
4
<span style="font-size: 13px;">- var items = ["one", "two", "three"]
- each item in items
   li= item
</span>

輸出:

1
2
3
4
<span style="font-size: 13px;"><li>one</li>
<li>two</li>
<li>three</li>
</span>

循環對象的鍵和值:

1
2
3
4
<span style="font-size: 13px;">- var obj = { foo: 'bar' }
- each val, key in obj
   li #{key}: #{val}
</span>

這會輸出 <li>foo: bar</li>

也能夠進行嵌套循環:

1
2
3
4
<span style="font-size: 13px;">- each user in users
   - each role in user.roles
     li= role
</span>

當一個屬性爲undefined,Jade會輸出空串,例如:

1
2
<span style="font-size: 13px;">textarea= user.signature
</span>

近期的Jade版本會輸出空字符串而不是undefined:

1
2
<span style="font-size: 13px;"><textarea></textarea>
</span>

命令行工具:bin/jade

輸出html到標準輸出(stdout):

1
2
<span style="font-size: 13px;">jade examples/*.jade --pipe
</span>

生成 examples/*.html :

1
2
<span style="font-size: 13px;">jade examples/*.jade
</span>

傳入參數:

1
2
<span style="font-size: 13px;">jade examples/layout.jade --options '{ locals: { title: "CSSer" }}'
</span>
相關文章
相關標籤/搜索