標籤:
Jade是一款高效能簡潔易懂的模板引擎,Jade是Haml的Javascript實現,在服務端(NodeJS)及用戶端均有支援。
功能
· 用戶端支援
· 超強的可讀性
· 靈活易用的縮排
· 塊擴充
· 代碼預設經過編碼處理以增強安全性
· 編譯及運行時的上下文錯誤報表
· 命令列編譯支援
· HTML5模式(使用!!!5文件類型)
· 可選的記憶體緩衝
· 聯合動態和靜態標記類
· 利用過濾器解析樹的處理
· 支援 Express JS
· 利用each透明的迴圈objects,arrays甚至不可枚舉對象
· 塊注釋
· 不需要標記首碼
· AST過濾器
· 過濾器
o :sass 需要安裝sass.js
o :less 需要安裝less.js
o :markdown 需要安裝markdown-js或node-discount
o :cdata
o :coffeescript 需要安裝coffee-script
· Vim文法檔案
· TextMate包
· Screencasts
其它語言實現
· php
· Scala
· Ruby
安裝
通過npm:
npm install jade
瀏覽器支援
可以通過下面命令將jade編譯為用戶端瀏覽器安全色的檔案:
$ make jade.js
或者,如果你已經通過npm安裝了uglifyjs(npminstalluglify-js),可以通過下面的命令同時建立兩個檔案:
$ make jade.min.js
公開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
· scope 執行範圍(this)
· locals 本地變數對象
· filename 處理異常及緩衝時使用
· cache 通過檔案名稱將Javascript緩衝在記憶體中
· debug 輸出產生的標記和函數體
· compiler 替換jade預設編譯引擎
文法
行尾
在解析前會將 CRLF 和 CR 轉換為 LF.
標記
標記是一行的第一個單詞:
html
會被轉換為 <html></html>
標記也可以有id:
div#container
這將被渲染成<div id=”container”></div>
如何處理類?
div.user-details
渲染為: <div class=”user-details”></div>
多個class?並且還有id?
div#foo.bar.baz
渲染為:<div id=”foo” class=”bar baz”></div>
總寫div確實很煩人,可以省略之:
#foo
.bar
輸出: <div id=”foo”></div><div class=”bar”></div>
標記文本
只需要將常值內容放在標記後面:
p wahoo!
渲染為 <p>wahoo!</p>.
酷,但是如何處理大段文本呢?
p
| foo bar baz
| rawr rawr
| super cool
| go jade go
渲染為 <p>foo bar baz rawr…..</p>
插入法?是的,這兩種類型的文本都可以使用插入法,如果我們傳入{ locals: { name: ‘一回’, email: ‘xianlihua[at]gmail.com’ }},可以這樣做:
#user #{name} <#{email}>
輸出:<div id=”user”>一回 <xianlihua[at]gmail.com></div>
出於某種原因需要輸出#{}?轉義之:
p \#{CSSer, 關注Javascript技術}
這樣就得到了:<p>#{CSSer, 關注Javascript技術}</p>
也可以使用反轉義變數!{html},下面的代碼將輸出script標記:
- var html = "<script></script>"
| !{html}
包含文本的嵌套標記也可以使用文字區塊:
label
| Username:
input(name=‘user[name]‘)
或者直接使用標記文本:
label Username:
input(name=‘user[name]‘)
只接受純文字的標記,如script,style,以及textarea不需要開頭的|字元,例如:
html
head
title CSSer, 關注Web前端技術
script
if (foo) {
bar();
} else {
baz();
}
再次作為替代方案,我們可以使用點號’.‘來表示一個文字區塊,例如:
p.
foo asdf
asdf
asdfasdfaf
asdf
asd.
輸出:
<p>foo asdf
asdf
asdfasdfaf
asdf
asd
.
</p>
如果點號’.‘與標記之間有空格,Jade解析其會忽略它,將其作為文本處理:
p .
輸出:
<p>.</p>
注釋
單行注釋當前看起來與Javascript一致,即“//”,單行注釋的內容必須放在同一行上:
// 一些段落
p foo
p bar
將會輸出:
<!-- 一些段落 -->
<p>foo</p>
<p>bar</p>
Jade也支援非緩衝注釋,只需增加一個橫杠:
//- 該行注釋將不會被輸出到解析後的頁面中
p foo
p bar
輸出:
<p>foo</p>
<p>bar</p>
塊注釋
塊注釋會依據縮排進行處理:
body
//
#content
h1 CSSer,關注Web前端技術
輸出:
<body>
<!--
<div id="content">
<h1>CSSer,關注Web前端技術</h1>
</div>
-->
</body>
Jade也支援條件注釋,例如:
body
/if IE
a(href=‘http://www.mozilla.com/en-US/firefox/‘) Get Firefox
輸出:
<body>
<!--[if IE]>
<a href="http://www.mozilla.com/en-US/firefox/">Get Firefox</a>
<![endif]-->
</body>
嵌套
Jade支援通過嵌套來以自然的方式定義標記:
ul
li.first
a(href=‘#‘) foo
li
a(href=‘#‘) bar
li.last
a(href=‘#‘) baz
塊擴充
塊擴充允許建立單行的簡潔嵌套標記,下面的樣本與上例輸出相同:
ul
li.first: a(href=‘#‘) foo
li: a(href=‘#‘) bar
li.last: a(href=‘#‘) baz
特性
目前Jade支援’(‘和’)‘的特性定界符。
a(href=‘/login‘, title=‘View login page‘) Login
另外我們也可以使用冒號(:)來作為分割符:
a(href: ‘/login‘, title: ‘註冊成為CSSer.com會員‘) Login
Boolean特性也被支援:
input(type="checkbox", checked)
值為變數的Boolean特性只有在值為true時輸出:
input(type="checkbox", checked: someValue)
分拆在多行也能正常解析:
input(type=‘checkbox‘,
name=‘agreement‘,
checked)
文件類型
利用!!!來增加頁面的文件類型:
!!!
將會輸出過渡型文件類型,然而:
!!! 5
將會輸出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">‘
};
要修改預設值只需改變:
jade.doctypes.default = ‘whatever you want‘;
過濾器
過濾器以冒號(:)作為首碼,如 :markdown 將會對文本進行函數處理,(一回註:類似Smarty的變數調節器),本頁開始處列出了目前Jade支援的過濾器。
body
:markdown
Woah! jade _and_ markdown, very **cool**
we can even link to [CSSer](http://www.csser.com)
渲染後:
<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>
過濾器也可以處理解析樹,通常過濾器可以正常處理文字區塊,但是通過傳入規則的塊過濾器可以做任何它能做的。
body
conditionals:
if role == ‘admin‘
p You are amazing
else
p Not so amazing
代碼
Jade目前支援三種類型的可執行代碼,第一種以-為首碼,不會被緩衝:
- var foo = ‘bar‘;
這可被用於條件或迴圈:
- for (var key in obj)
p= obj[key]
由於Jade的緩衝技術,下面的代碼是有效:
- if (foo)
ul
li yay
li foo
li worked
- else
p oh no! you are not in csser.com
甚至詳細的迭代迴圈:
- if (items.length)
ul
- items.forEach(function(item){
li= item
- })
任何你希望的都可以實現!
接下來我們轉義了緩衝代碼,用於緩衝傳回值,以等號(=)作為首碼:
- var foo = ‘bar‘
= foo
h1= foo
輸出: bar<h1>bar</h1>. 被’=‘緩衝的代碼會預設經過轉義以增強安全性,要輸出為轉義的值需要使用 !=:
p!= aVarContainingMoreHTML
一個允許使用”vanilla”Javascript的例外,是 – each 標記,其表現形式為:
- each VAL[, KEY] in OBJ
實現迴圈數組的例子:
- var items = ["one", "two", "three"]
- each item in items
li= item
輸出:
<li>one</li>
<li>two</li>
<li>three</li>
迴圈對象的鍵和值:
- var obj = { foo: ‘bar‘ }
- each val, key in obj
li #{key}: #{val}
這會輸出 <li>foo: bar</li>
也可以進行嵌套迴圈:
- each user in users
- each role in user.roles
li= role
當一個屬性為undefined,Jade會輸出空串,例如:
textarea= user.signature
近期的Jade版本會輸出Null 字元串而不是undefined:
<textarea></textarea>
命令列工具:bin/jade
輸出html到標準輸出(stdout):
jade examples/*.jade --pipe
產生 examples/*.html :
jade examples/*.jade
傳入參數:
jade examples/layout.jade --options ‘{ locals: { title: "CSSer" }}‘
[完]
js 模板引擎 jade使用文法