jade(pug)
由於商標版權問題,Jade 已經改名為了 Pug,github地址github.com/pugjs/pug
Jade 是一個高效能的模板引擎,它是用 JavaScript 實現的,並且可以供 Node 使用,當然還支援其他語言。
檔案字尾名為.pug(.jade)
jade優點
- 可讀性高
- 靈活的縮排
- 塊展開
- 程式碼預設經過編碼處理(轉義),安全性高
- 執行時和編譯時上下文錯誤報告
- 支援命令列編譯
- 支援html5模式
- 在記憶體中快取(可選)
- 原生支援 Express
- 合併動態和靜態標籤類
- 過濾器
關於Ejs或者其他模板引擎與jade比較,可以看看這篇文章www.zhihu.com/question/20…
安裝
npm安裝建議安裝個nrm來進行源管理.
npm install pug -g
npm install pug-cli -g複製程式碼
測試demo
為了方便編寫程式碼,最好把編譯器的tab設定:2.
// index.jade
doctype html
html
head
title jade test
body
h2 jade study複製程式碼
粗暴的編譯方法
pug index.jade
// index.html
<!DOCTYPE html><html><head><title>jade test</title></head><body><h2>jade study </h2></body></html>複製程式碼
發現編譯後的程式碼不具備可讀性.
pug -- help
Options:
-P, --pretty compile pretty HTML output ## 輸出漂亮結構的HTML
-D, --no-debug compile without debugging (smaller functions) ## 不帶除錯的編譯
-w, --watch watch files for changes and automatically re-render ## 對某個檔案的變動保持監控
-E, --extension <ext> specify the output file extension ## 指定輸出副檔名
-s, --silent do not output logs ## 不輸出日誌複製程式碼
// 重新編譯
pug -P index.jade
<!DOCTYPE html>
<html>
<head>
<title>jade test</title>
</head>
<body>
<h2>jade study </h2>
</body>
</html>複製程式碼
自動編譯
只是為了學習,這裡只要設定-w -P .開發中通過打包工具來進行自動編譯.
// 命令列工具推薦使用Cmder
λ pug -P -w index.jade
watching index.jade
rendered index.html複製程式碼
Express與Pug
Pug完全整合了一個流行的Node.js Web框架Express,作為支援的檢視引擎。 看看Express是如何將Pug與Express整合的完美指南。
在Express中,環境變數NODE_ENV旨在向Web應用程式通知執行環境:無論是在開發中還是在生產中。 Express和Pug自動修改生產環境中的幾個選項的預設值,為使用者提供更好的開箱即用體驗。 具體來說,當process.env.NODE_ENV設定為“production”,Pug與Express一起使用時,compileDebug選項預設為false,而cache選項為true。
API
標籤屬性
- id,class寫法
// 編譯前
p.title class寫法1
p(class='title') class寫法2
p#tit id寫法1
p(id='tit2') id寫法2
// 編譯後
<p class="title">class寫法1</p>
<p class="title">class寫法2</p>
<p id="tit">id寫法</p>
<p id="tit2">id寫法2 </p>複製程式碼
// 編譯前
- var classArr = ['small','medium','large']
a(class= classArr)
a.test(class = classArr class=['add'])
// 編譯後
<a class="small medium large"></a>
<a class="test small medium large add"></a>複製程式碼
它也可以是將類名對映到true或false值的物件.
//編譯前
- var active = 'select'
a(class={active: active === 'select'} )
// 編譯後
<a class="active"></a>複製程式碼
- 其他屬性
通過()來依次編寫屬性,多個用逗號隔開.
//編譯前
a(class='baidu' ,title='baidu' href='www.baidu.com') 百度
//編譯後
<a class="baidu" title="baidu" href="www.baidu.com">百度</a>複製程式碼
- 也支援所有正常的javascript表示式
// 編譯前
- var flag = true //注意這裡使用變數要記得新增-符號.
h2(class=flag ? 'flag': '')
// 編譯後
<h2 class="flag"></h2>複製程式碼
- 多個屬性的另外寫法
其實就是換號縮排
// 編譯前
a(
title='baidu',
href='www.baidu.com',
class='links'
)
// 編譯後
<a class="links" title="baidu" href="www.baidu.com"></a>複製程式碼
如果您有一個非常長的屬性,並且您的JavaScript執行時支援ES2015模板字串,則可以使用該語法的屬性:
// 編譯前
input(data-json=`
{
"very-long": "piece of ",
"data": true
}
`)
// 編譯後
<input data-json="
{
"very-long": "piece of ",
"data": true
}
">複製程式碼
- 引用屬性
如果你的屬性名稱包含了與JavaScript語法衝突的字元,請使用""或''引用,或使用逗號分隔不同的屬性。
官網舉了個Angular 2的例子.
//(click)='play()',這裡(click)會被當作一個函式呼叫而不是一個屬性名字來解析.
// 編譯前
div(class='div-class' (click)='play()')
// 編譯後報錯
div(class='div-class' (click)='play()')
---------------------^複製程式碼
正確寫法
// 編譯前
div(class='div-class' '(click)'='play()')
div(class='div-class', (click) = 'play()')
// 編譯後
<div class="div-class" (click)="play()"></div>
<div class="div-class" (click)="play()"></div>複製程式碼
- 屬性插值
以前版本的Pug / Jade支援如下插值語法(不再支援):
//編譯前
- var url = 'www.baidu.com'
a(href='/#{url}') links
//編譯後 已不再支援
<a href="/#{url}">links</a>複製程式碼
新的寫法
// 編譯前
- var url = 'demo.com'
a(href='/' + url) links
- var url2 = 'www.baidu.com'
a(href = url2 ) 百度
// 編譯後
<a href="/demo.com">links</a>
<a href="www.baidu.com">百度 </a>複製程式碼
如果你的javascript執行環境支援ES 2015.那麼Pug支援模板字串語法
// 編譯前
- var size1 = 'small'
- var size2 = 'medium'
- var size3 = 'large'
button(
type='button',
class='btn btn-' + size1 + ' ' + 'btn-' + size2 + ' ' + 'btn-' + size3
)
button(
type='button',
class=`btn btn-$(size1) btn-$(size2) btn(size3)`
)
// 編譯後
<button class="btn btn-small btn-medium btn-large" type="button"></button>
<button class="btn btn-small btn-medium btn-large" type="button"></button>複製程式碼
- 未轉義屬性
預設情況下,會轉義所有屬性(用轉義序列代替特殊字元),以防止諸如跨站點指令碼之類的攻擊。 如果必須需要使用特殊字元,可以使用!=而不是=。
// 編譯前
div(title="<code>")
div(title!="<code>")
// 編譯後
<div title="<code>"></div>
<div title="<code>"></div>複製程式碼
- 布林屬性
布林屬性由Pug映象,並接受布林值(true和false)。 當沒有指定值時,預設為true。
// 編譯前
input(type='radio' checked)
input(type='radio' checked=true)
input(type='radio' checked=false)
// 編譯後
<input type="radio" checked>
<input type="radio" checked>
<input type="radio">複製程式碼
- style屬性
style屬性可以是一個字串(像任何普通屬性),但它也可以是一個物件
// 編譯前
p(style={fontSize: '14px',color: 'red'})
// 編譯後
<p style="fontSize:14px;color:red;"></p>複製程式碼
Case
case語句是JavaScript Switch語句的縮寫,並採用以下形式:
// 編譯前
- var friendsNum = 4
case friendsNum
when 0
p you have not friend
when 1
p you has one friend
default
p you has #{friendsNum} friends
// 編譯後
<p>you has 4 friends </p>複製程式碼
// 編譯前
- var friendsNum = 1
case friendsNum
when 0
when 1
p you has one friend
default
p you has #{friendsNum} friends
// 編譯後
<p>you has one friend</p>複製程式碼
當然也支援break;
// 編譯前
- var friendsNum = 0
case friendsNum
when 0
- break
when 1
p you has one friend
default
p you has #{friendsNum} friends
// 編譯後
無內容複製程式碼
也可以使用塊擴充套件語法
// 編譯前
- var friendsNum = 1
case friendsNum
when 0
when 1: p you has one friend
default: p you has #{friendsNum} friends
// 編譯後
<p>you has one friend</p>複製程式碼
Code
Pug可以在你的模板中編寫內建的JavaScript程式碼。 有三種型別的程式碼。
- Unbuffered Code
不直接新增任何的輸出
// 編譯前
- for(var i = 0; i < 3;i++)
li item
// 編譯後
<li>item</li>
<li>item</li>
<li>item</li>複製程式碼
// 編譯前
- var nameList = ['kobe','cpul','james']
each item in nameList
li=item
// 編譯後
<li>kobe</li>
<li>cpul</li>
<li>james</li>複製程式碼
- Buffered Code
以=開頭,並輸出評估模板中JavaScript表示式的結果。 為了安全起見,首先HTML被轉義:
// 編譯前
p
= 'this is code template <code>'
p= 'this is code template' + '<code>'
// 編譯後
<p>this is code template <code>
</p>
<p>this is code template<code></p>複製程式碼
- Unescaped Buffered Code
未轉義的程式碼以!=開頭,並輸出評估模板中JavaScript表示式的結果。 這不會進行任何轉義,所以對使用者輸入是不安全的:
// 編譯前
p
!= 'this is code template <code>'
p!= 'this is code template' + '<code>'
// 編譯後
<p>this is code template <code>
</p>
<p>this is code template<code></p>複製程式碼
Comments註釋
- 單行註釋
// 編譯前
// 這是一個註釋
p 這是一個註釋
// 編譯後
<!-- 這是一個註釋-->
<p>這是一個註釋</p>複製程式碼
Pug還有種註釋寫法,只需新增連字元'-'即可。這些僅用於對Pug程式碼本身進行註釋,編譯後不會出現在HTML中。
// 編譯前
//- 這是一個註釋
p 這是一個註釋
// 編譯後
<p>這是一個註釋</p>複製程式碼
- 塊級註釋
// 編譯前
//-
註釋不會出現在模板中
真的
//
第一行註釋
第二行註釋
// 編譯後
<!--
第一行註釋
第二行註釋
-->複製程式碼
- 條件註釋
對於條件註釋,Pug沒有任何特殊的語法,下面例子這是為舊版本的Internet Explorer新增後備標記的特殊方法,但是由於以<開頭的所有行被視為純文字,普通的HTML樣式條件註釋將會很好。
// 編譯前
<!--[if IE 8]>
<p class="lt-ie9">
<![endif]-->
// 編譯後
<!--[if IE 8]>
<p class="lt-ie9">
<![endif]-->複製程式碼
Conditionals條件語句
// 編譯前
- var user = {name: 'kobe'}
- var flag = true
#user
if user.name
h3.user-title #{user.name}
else if flag
p flag is #{flag}
else
p default
// 編譯後
<div id="user">
<h3 class="user-title">kobe</h3>
</div>複製程式碼
Pug也支援另外一個關鍵字 unless
// 編譯前
- var user = {name: 'kobe'}
#user
unless !user.name
h2 #{user.name}
// 編譯後
<div id="user">
<h2>kobe</h2>
</div>複製程式碼
doctype
// 編譯前
doctype html
// 編譯後
<!DOCTYPE html>複製程式碼
Filters過濾器
過濾器可讓你在Pug模板中使用其他語言。也就是支援外掛的使用,通過外掛對模板內容進行過濾,處理,輸出.如scss,less,markdown,coffee-script....
先全域性安裝這些外掛
npm install --save jstransformer-coffee-script
npm install --save jstransformer-markdown-it複製程式碼
// 編譯前
h2 MarkDown
:markdown-it
#### this is markdown filter
[link](http://www.baidu.com)
:coffee-script
console.log('this is coffee-script');
// 編譯後
<h2>MarkDown</h2><h4>this is markdown filter</h4>
<p><a href="http://www.baidu.com">link</a></p>
(function() {
console.log('this is coffee-script');
}).call(this);複製程式碼
缺點:不能支援動態內容或選項。
Includes包含
Pug允許你靜態包含一段 Jade, 或者別的存放在單個檔案中的東西比如 CSS, HTML 非常常見的例子是包含頭部和頁尾。 假設我們有一個下面目錄結構的資料夾:
- /index.jade
- /includes/
-/head.jade
-/footer.jade複製程式碼
// index.jade
doctype html
html
include includes/header.jade
body
h1 這是主題內容
include includes/footer.jade複製程式碼
// header.jade
header
title 通用的header
script(src='/jQuery.js')
link(href='reset.css')複製程式碼
// footer.jade
footer#footer
p Copyright (c) foobar複製程式碼
// 編譯後
<!DOCTYPE html>
<html>
<header>
<title>通用的header</title>
<script src="/jQuery.js"></script>
<link href="reset.css">
</header>
<body>
<h1>這是主題內容</h1>
<footer id="footer">
<p>Copyright (c) foobar</p>
</footer>
</body>
</html>複製程式碼
include 可以包含比如 HTML 或者 CSS 這樣的內容。給定一個副檔名後,Jade 不會把這個檔案當作一個 Jade 原始碼,並且會把它當作一個普通文字包含進來:
// 格式
style
include style.css
script
include script.js複製程式碼
甚至可以通過include結合過濾器使用
// 引入article.md
include:markdown-it article.md複製程式碼
模板繼承
Jade 支援通過 block 和 extends 關鍵字來實現模板繼承。 一個塊就是一個 Jade 的 block ,它將在子模板中實現,同時是支援遞迴的。
如果需要,Pug block 可以提供預設內容,但是可以通過block scripts, block content, 和 block foot來顯示如下所示的可選項。
// 基本使用
// 編譯前
block desc
p 這是block context
block desc
// 編譯後
<p>這是block context</p>複製程式碼
// index.jade
doctype html
html
include includes/header.jade
body
block content
block foot
.footer some footer content複製程式碼
現在要繼承上面那個index.jade,只需建立一個新檔案,並使用extend指令,如下所示,給出路徑。 您現在可以定義一個或多個block將覆蓋父塊內容的塊.
在Pug v1中,如果沒有給定副檔名,那麼.pug會自動附加到路徑上,但是在Pug v2中,這個行為已被棄用。
// index.jade
doctype html
html
block scripts
script(src='/jquery.js')
body
block content
block foot
.footer some footer content複製程式碼
// page.jade
extends index.jade
block scripts
script(src='/jquery.js')
script(src='/page.js')
block content
h2 page.jade
- var pets = ['cat', 'dog']
each petName in pets
li=petName複製程式碼
// page.jade 編譯後
<!DOCTYPE html>
<html>
<script src="/jquery.js"></script>
<script src="/page.js"></script>
<body>
<h2>page.jade</h2>
<li>cat</li>
<li>dog</li>
<div class="footer"> some footer content</div>
</body>
</html>複製程式碼
同樣可以在一個子塊裡繼續新增塊,就像下面實現的塊 content 裡又定義了兩個可以被實現的塊 sidebar 和 primary,或者子模板直接實現 content。
block content
.sidebar
block sidebar
p nothing
.primary
block primary
p nothing複製程式碼
Pug允許你 替換 (預設)、 前置 和 追加 blocks. 使用 block append 或 block prepend 時 block 是可選的:
// pageTwo.jade
extend page.jade
append scripts
script(src='/pageTwo.js')複製程式碼
// 編譯後
<!DOCTYPE html>
<html>
<script src="/jquery.js"></script>
<script src="/page.js"></script>
<script src="/pageTwo.js"></script>
<body>
<h2>page.jade</h2>
<li>cat</li>
<li>dog</li>
<div class="footer"> some footer content</div>
</body>
</html>複製程式碼
Interpolation插值
// 編譯前
- var author = 'xyz'
- var date = '2017-4'
h2
p writer was by #{author.toUpperCase()}
p date is #{date}
// 編譯後
<h2>
<p>writer was by XYZ</p>
<p>date is 2017-4</p>
</h2>複製程式碼
如果你想保持#{}插值符號,可以使用#{或者'\'.
Iteration迭代
- each
// 編譯前
- var arr = [1,2,3,4]
each val,index in arr
li= index + ':' + val
// 編譯後
<li>0:1</li>
<li>1:2</li>
<li>2:3</li>
<li>3:4</li>複製程式碼
- while
// 編譯前
- var arr = 4
while arr > 0
li= arr--
// 編譯後
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>複製程式碼
Mixins
Mixins允許您建立可重用的Pug block。
// 編譯前
mixin lists
p this is a mixin block
+lists
+lists
// 編譯後
<p>this is a mixin block</p>
<p>this is a mixin block</p>複製程式碼
mixins可以為一個帶引數的函式
// 編譯前
mixin link(href,name)
a(href=href)= name
+link('www.baidu.com','百度')
// 編譯後
<a href="www.baidu.com">百度</a>複製程式碼
mixins也可以使用一個block來作為內容
// 編譯前
mixin lists(names)
p= 'my name is ' + names
if block
block
else
p not provided content
+lists('kobe')
+lists('cpul')
p block content
// 編譯後
<p>my name is kobe</p>
<p>not provided content</p>
<p>my name is cpul</p>
<p>block content</p>複製程式碼
未知數量引數(...)的mixins.
// 編譯前
mixin lists(className,...items)
ul(class=className)
each item in items
li= item
+lists('demo',1,2,3)
// 編譯後
<ul class="demo">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>複製程式碼
Tags
預設情況下,一行開頭的文字(或僅在空格之後)代表一個html標籤。 縮排的標籤是巢狀的,建立了像html的樹結構。
Pug可以判斷出哪些元素是自閉,您還可以通過簡單地附加'/'字元來明確地自己關閉標籤:
為了節省空間,Pug提供巢狀標記的內聯語法。
// 編譯前
p: span 內聯
// 編譯後
<p><span>內聯</span></p>複製程式碼
Pug的缺點
凡事不可能完美.Pug也有自己的弊端.
- 可移植性差
- 對新手除錯不方便
- 效能不是很好