js pug 代码_pug模板引擎(原jade)
前面的話
為什么要引入pug,pug有什么特別之處呢?有一些嵌套層次較深的頁面,可能會(huì)出現(xiàn)巢狀嵌套,如下圖所示
在后期維護(hù)和修改時(shí),一不小心少了一個(gè)尖括號(hào),或者某個(gè)標(biāo)簽的開始和閉合沒有對(duì)應(yīng)上,就會(huì)導(dǎo)致DOM結(jié)構(gòu)的混亂甚至是錯(cuò)誤。所以,有人發(fā)明了HAML,它最大的特色就是使用縮進(jìn)排列來代替成對(duì)標(biāo)簽。受HAML的啟發(fā),pug進(jìn)行了javascript的實(shí)現(xiàn)。
Pug原名不叫Pug,是大名鼎鼎的jade,后來由于商標(biāo)的原因,改為Pug,哈巴狗。其實(shí)只是換個(gè)名字,語法都與jade一樣。丑話說在前面,Pug有它本身的缺點(diǎn)——可移植性差,調(diào)試?yán)щy,性能并不出色,但使用它可以加快開發(fā)效率。本文將詳細(xì)介紹pug模板引擎
安裝
使用npm安裝pug
$ npm install pug
但運(yùn)行pug命令時(shí),提示pug命令未找到
這時(shí),需要安裝pug命令行工具pug-cli
[注意]一定要全局安裝pug-cli,否則無法正常編譯
npm install pug-cli -g
再運(yùn)行pug命令時(shí),正常執(zhí)行
命令行
在學(xué)習(xí)pug基礎(chǔ)語法之前,首先要了解pug的命令行的使用
【基礎(chǔ)編譯】
將如下內(nèi)容輸入文件中,并命名為index.pug
html
head
title aaa
body
在命令行中敲入pug index.pug即可實(shí)現(xiàn)基礎(chǔ)編譯
在當(dāng)前目錄下生成一個(gè)index.html,是index.pug編譯后的結(jié)果
【sublime兩列設(shè)置】
但是,這樣查看并不方便。下面將sublime設(shè)置為兩列放置,將index.pug和index.html分別放置在左右兩列,方便查看
【自動(dòng)編譯】
使用pug -w功能可以實(shí)現(xiàn)自動(dòng)編譯
更改index.pug文件并保存后,index.html文件會(huì)實(shí)時(shí)更新為最新的編譯的文件
【標(biāo)準(zhǔn)版HTML】
如上所示,默認(rèn)地,pug編譯出的HTML文件是壓縮版的。如果要編譯標(biāo)準(zhǔn)版的HTML文件,需要設(shè)置-P參數(shù)
pug index.html -P
【路徑設(shè)置】
如果并不希望在當(dāng)前目錄下輸入編譯后的HTML文件,而是有自定義目錄的需求,則需要設(shè)置-o參數(shù)
如下設(shè)置,index.html將輸入到a目錄下面,如果a目錄不存在,則會(huì)新建a目錄
pug index.pug -o a
【重命名】
默認(rèn)地,編譯后的HTML與pug文件同名。如果需要重命名,則可以進(jìn)行如下設(shè)置
通過如下設(shè)置,可以同時(shí)設(shè)置路徑和名稱
[注意]這里的路徑必須提前建立好,否則不會(huì)成功
pug
最終,test.html文件被保存到templates目錄下
【批量編譯】
假設(shè),編譯href目錄下所有的pug文件
結(jié)構(gòu)語法
下面介紹關(guān)于結(jié)構(gòu)的基礎(chǔ)語法
標(biāo)簽
【樹狀】
在默認(rèn)情況下,在每行文本的開頭(或者緊跟白字符的部分)書寫這個(gè) HTML 標(biāo)簽的名稱。使用縮進(jìn)來表示標(biāo)簽間的嵌套關(guān)系,這樣可以構(gòu)建一個(gè) HTML 代碼的樹狀結(jié)構(gòu)
ul
li Item A
li Item B
li Item C
【內(nèi)聯(lián)】
為了節(jié)省空間, Pug 嵌套標(biāo)簽提供了一種內(nèi)聯(lián)式語法
a: img
【自閉合】
Pug知道哪些元素是自閉合的,也可以通過在標(biāo)簽后加上 / 來明確聲明此標(biāo)簽是自閉合的
img
input
img/input/
【DOCTYPE】
HTML5的DOCTYPE書寫如下
doctype html
也可以自定義一個(gè) doctype 字面值
doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
內(nèi)容
Pug 提供了三種常用的方式來放置內(nèi)容
【管道文本】
這是最簡(jiǎn)單的向模板添加純文本的方法。只需要在每行前面加一個(gè) | 字符,這個(gè)字符在類 Unix 系統(tǒng)下常用作“管道”功能,因此得名
| 純文本當(dāng)然也可以包括 HTML內(nèi)容。
p| 但它必須單獨(dú)起一行。
【標(biāo)簽內(nèi)文本】
這實(shí)際上是最常見的情況,文本只需要和標(biāo)簽名隔開一個(gè)空格即可
p 純文本當(dāng)然也可以包括 HTML 內(nèi)容。
【嵌入大段文本】
有時(shí)可能想要寫一個(gè)大段文本塊。比如嵌入腳本或者樣式。只需在標(biāo)簽后面接一個(gè) .即可
[注意]不要有空格
script.if(usingPug)
console.log('這是明智的選擇。')elseconsole.log('請(qǐng)用 Pug。')
屬性
標(biāo)簽屬性和 HTML 語法非常相似,它們的值就是普通的 JavaScript 表達(dá)式。可以用逗號(hào)作為屬性分隔符,也可以不加逗號(hào)
a(href='baidu.com') 百度= '\n'a(class='button' href='baidu.com') 百度= '\n'a(class='button', href='baidu.com') 百度
【多行屬性】
如果有很多屬性,可以把它們分幾行寫
input(
type='checkbox'name='agreement'
checked)
【長(zhǎng)屬性】
如果有一個(gè)很長(zhǎng)的屬性,并且JavaScript運(yùn)行時(shí)引擎支持ES2015模板字符串,可以使用它來寫屬性值
input(data-json=`
{"非常": "長(zhǎng)的","數(shù)據(jù)": true}
`)
【特殊字符】
如果屬性名稱中含有某些奇怪的字符,可能會(huì)與 JavaScript 語法產(chǎn)生沖突的話,可以將它們使用 "" 或者 '' 括起來。還可以使用逗號(hào)來分割不同的屬性
div(class='div-class', (click)='play()')
div(class='div-class' '(click)'='play()')
【轉(zhuǎn)義屬性】
默認(rèn)情況下,所有的屬性都經(jīng)過轉(zhuǎn)義(即把特殊字符轉(zhuǎn)換成轉(zhuǎn)義序列)來防止諸如跨站腳本攻擊之類的攻擊方式。如果要使用特殊符號(hào),需要使用 != 而不是 =
[注意]未經(jīng)轉(zhuǎn)義的緩存代碼十分危險(xiǎn)。必須正確處理和過濾用戶的輸入來避免跨站腳本攻擊
div(escaped="")
div(unescaped!="")
【布爾值】
在Pug中,布爾值屬性是經(jīng)過映射的,這樣布爾值(true和false)就能接受了。沒有指定值時(shí),默認(rèn)是true
input(type='checkbox' checked)= '\n'input(type='checkbox' checked=true)= '\n'input(type='checkbox' checked=false)= '\n'input(type='checkbox' checked=true.toString())
【行內(nèi)樣式】
style(樣式)屬性可以是一個(gè)字符串(就像其他普通的屬性一樣)還可以是一個(gè)對(duì)象
a(style={color: 'red', background: 'green'})
【類和ID】
類可以使用 .classname 語法來定義,ID 可以使用 #idname 語法來定義
考慮到使用 div 作為標(biāo)簽名這種行為實(shí)在是太常見了,所以如果省略掉標(biāo)簽名稱的話,它就是默認(rèn)值
a.button
.content="\n"a#main-link
#content
標(biāo)簽嵌入
標(biāo)簽支持一種標(biāo)簽嵌入的寫法,形式如下
#[標(biāo)簽名(標(biāo)簽屬性) 標(biāo)簽內(nèi)容]
對(duì)于內(nèi)聯(lián)標(biāo)簽來說,這種寫法比較簡(jiǎn)單
p.
這是一個(gè)很長(zhǎng)很長(zhǎng)而且還很無聊的段落,還沒有結(jié)束,是的,非常非常地長(zhǎng)。
突然出現(xiàn)了一個(gè) #[strong 充滿力量感的單詞],這確實(shí)讓人難以 #[em 忽視]。
【空格調(diào)整】
Pug 默認(rèn)會(huì)去除一個(gè)標(biāo)簽前后的所有空格,而標(biāo)簽嵌入功能可以在需要嵌入的位置上處理前后空格
p
|如果我不用嵌入功能來書寫,一些標(biāo)簽比如
strong strong
|和
em em
|可能會(huì)產(chǎn)生意外的結(jié)果。
p.
如果用了嵌入,在 #[strong strong] 和 #[em em] 旁的空格就會(huì)讓我舒服多了。
注釋
【單行注釋】
單行注釋和 JavaScript 類似,但是必須獨(dú)立一行
//一些內(nèi)容
p foo
p bar
【不輸出注釋】
只需要加上一個(gè)橫杠,就可以使用不輸出注釋
//- 這行不會(huì)出現(xiàn)在結(jié)果里
p foo
p bar
【塊注釋】
body//隨便寫多少字
都沒關(guān)系。
【條件注釋】
Pug 沒有特殊的語法來表示條件注釋(conditional comments)。不過因?yàn)樗幸?< 開頭的行都會(huì)被當(dāng)作純文本,因此直接寫一個(gè) HTML 風(fēng)格的條件注釋也是沒問題的
邏輯語法
以下是關(guān)于模板邏輯的語法
JS代碼
【不輸出的代碼】
用 - 開始一段不直接進(jìn)行輸出的代碼
- for (var x = 0; x < 3; x++)
li item
【輸出的代碼】
用=開始一段帶有輸出的代碼,它應(yīng)該是可以被求值的一個(gè)JavaScript表達(dá)式。為安全起見,它將被HTML轉(zhuǎn)義
p= '這個(gè)代碼被 了!'p= '這個(gè)代碼被 了!'
【不轉(zhuǎn)義的輸出代碼】
用 != 開始一段不轉(zhuǎn)義的,帶有輸出的代碼。這將不會(huì)做任何轉(zhuǎn)義,所以用于執(zhí)行用戶的輸入將會(huì)不安全
p!= '這段文字 沒有 被轉(zhuǎn)義!'p!= '這段文字' + '沒有 被轉(zhuǎn)義!'
變量
【內(nèi)容變量】
使用=或#{}來進(jìn)行變量的真實(shí)值替換
- var title = "On Dogs: Man's Best Friend";
- var author = "enlore";
- var theGreat = "轉(zhuǎn)義!";
h1=title
p #{author} 筆下源于真情的創(chuàng)作。
p 這是安全的:#{theGreat}
在?#{?和?}?里面的代碼也會(huì)被求值、轉(zhuǎn)義,并最終嵌入到模板的渲染輸出中
- var msg = "not my inside voice";
p This is #{msg.toUpperCase()}
Pug 足夠聰明來分辨到底哪里才是嵌入表達(dá)式的結(jié)束,所以不用擔(dān)心表達(dá)式中有?},也不需要額外的轉(zhuǎn)義
p 不要轉(zhuǎn)義 #{'}'}!
如果需要表示一個(gè)?#{?文本,可以轉(zhuǎn)義它,也可以用嵌入功能來生成
p Escaping works with \#{interpolation}
p Interpolation works with #{'#{interpolation}'} too!
使用!{}嵌入沒有轉(zhuǎn)義的文本進(jìn)入模板中
- var riskyBusiness = "我希望通過外籍教師 Peter 找一位英語筆友。";
.quote
p 李華:!{riskyBusiness}
[注意]如果直接使用用戶提供的數(shù)據(jù),未進(jìn)行轉(zhuǎn)義的內(nèi)容可能會(huì)帶來安全風(fēng)險(xiǎn)
【屬性變量】
如果要在屬性當(dāng)中使用變量的話,需要進(jìn)行如下操作
- var url = 'pug-test.html';
a(href='/' + url) 鏈接
= '\n'
- url = 'https://example.com/'
a(href=url) 另一個(gè)鏈接
如果JavaScript運(yùn)行時(shí)支持 ECMAScript 2015 模板字符串,還可以使用下列方式來簡(jiǎn)化屬性值
- var btnType = 'info'
- var btnSize = 'lg'
button(type='button' class='btn btn-' + btnType + ' btn-' + btnSize)
= '\n'
button(type='button' class=`btn btn-${btnType} btn-${btnSize}`)
&attributes?語法可以將一個(gè)對(duì)象轉(zhuǎn)化為一個(gè)元素的屬性列表
div#foo(data-bar="foo")&attributes({'data-foo': 'bar'})
- var attributes = {};
- attributes.class = 'baz';
div#foo(data-bar="foo")&attributes(attributes)
【變量來源】
變量來源有三種,分別是pug文件內(nèi)部、命令行參數(shù)和外部JSON文件
1、pug文件內(nèi)部
2、命令行參數(shù)
使用--obj參數(shù),就可以跟隨一個(gè)對(duì)象形式的參數(shù)
3、外部JSON文件
使用-O,跟隨一個(gè)JSON文件的路徑即可
這三種方式,pug文件內(nèi)部的變量?jī)?yōu)先級(jí)最多,而外部JSON文件和命令行傳參優(yōu)先級(jí)相同
如下所示,外部JSON文件和命令行傳參兩種方式都存在,由于--obj寫在-w后面,最終以命令行傳參為準(zhǔn)
條件
Pug 的條件判斷的一般形式的括號(hào)是可選的,所以可以省略掉開頭的 -,效果完全相同。類似一個(gè)常規(guī)的 JavaScript 語法形式
【if else】
- var user = { description: 'foo bar baz'}- var authorised = false#userifuser.description
h2.green 描述
p.description=user.descriptionelse ifauthorised
h2.blue 描述
p.description.
用戶沒有添加描述。
不寫點(diǎn)什么嗎……elseh2.red 描述
p.description 用戶沒有描述
Pug 同樣也提供了它的反義版本 unless
unless user.isAnonymous
p 您已經(jīng)以 #{user.name} 的身份登錄。
【switch】
case 是 JavaScript 的 switch 指令的縮寫,并且它接受如下的形式
- var friends = 10
casefriends
when0p 您沒有朋友
when1p 您有一個(gè)朋友defaultp 您有 #{friends} 個(gè)朋友
在某些情況下,如果不想輸出任何東西的話,可以明確地加上一個(gè)原生的 break 語句
- var friends = 0
casefriends
when0
- breakwhen1p 您的朋友很少defaultp 您有 #{friends} 個(gè)朋友
也可以使用塊展開的語法
- var friends = 1
casefriends
when0: p 您沒有朋友
when1: p 您有一個(gè)朋友default: p 您有 #{friends} 個(gè)朋友
循環(huán)
Pug 目前支持兩種主要的迭代方式: each 和 while
【each】
這是 Pug 的首選迭代方式
ul
each valin [1, 2, 3, 4, 5]
li= val
可以在迭代時(shí)獲得索引值
ul
each val, indexin ['〇', '一', '二']
li= index + ':' + val
能夠迭代對(duì)象中的鍵值
ul
each val, indexin {1:'一',2:'二',3:'三'}
li= index + ':' + val
用于迭代的對(duì)象或數(shù)組僅僅是個(gè) JavaScript 表達(dá)式,因此它可以是變量、函數(shù)調(diào)用的結(jié)果,又或者其他
- var values =[];
ul
each valin values.length ? values : ['沒有內(nèi)容']
li= val
還能添加一個(gè) else 塊,這個(gè)語句塊將會(huì)在數(shù)組與對(duì)象沒有可供迭代的值時(shí)被執(zhí)行
- var values =[];
ul
each valinvalues
li=valelseli 沒有內(nèi)容
[注意]也可以使用 for 作為 each 的別稱
【while】
也可以使用 while 來創(chuàng)建一個(gè)循環(huán)
- var n = 0;
ulwhile n < 4li= n++
混入
混入是一種允許在 Pug 中重復(fù)使用一整個(gè)代碼塊的方法
//- 定義
mixin list
ul
li foo
li bar
li baz//- 使用
+list+list
混入可以被編譯成函數(shù)形式,并傳遞一些參數(shù)
mixin pet(name)
li.pet=name
ul+pet('貓')+pet('狗')+pet('豬')
混入也可以把一整個(gè)代碼塊像內(nèi)容一樣傳遞進(jìn)來
mixin article(title)
.article
.article-wrapper
h1=titleifblock
blockelsep 沒有提供任何內(nèi)容。+article('Hello world')+article('Hello world')
p 這是我
p 隨便寫的文章
混入也可以隱式地,從“標(biāo)簽屬性”得到一個(gè)參數(shù) attributes
也可以直接用 &attributes 方法來傳遞 attributes 參數(shù)
mixin link(href, name)
a(class!=attributes.class href=href)=name+link('/foo', 'foo')(class="btn")
[注意]+link(class="btn")?等價(jià)于?+link()(class="btn"),因?yàn)?Pug 會(huì)判斷括號(hào)內(nèi)的內(nèi)容是屬性還是參數(shù)。但最好使用后面的寫法,明確地傳遞空的參數(shù),確保第一對(duì)括號(hào)內(nèi)始終都是參數(shù)列表
可以用剩余參數(shù)(rest arguments)語法來表示參數(shù)列表最后傳入若干個(gè)長(zhǎng)度不定的參數(shù)
mixin list(id, ...items)
ul(id=id)
each iteminitems
li=item+list('my-list', 1, 2, 3, 4)
文件包含
包含(include)功能允許把另外的文件內(nèi)容插入進(jìn)來
//- index.pug
doctype html
html
include includes/head.pug
body
h1 我的網(wǎng)站
p 歡迎來到我這簡(jiǎn)陋得不能再簡(jiǎn)陋的網(wǎng)站。
include includes/foot.pug
//- includes/head.pug
head
title 我的網(wǎng)站
script(src='/javascripts/jquery.js')
script(src='/javascripts/app.js')
//- includes/foot.pug
footer#footer
p Copyright (c) foobar
被包含的如果不是 Pug 文件,那么就只會(huì)當(dāng)作文本內(nèi)容來引入
//- index.pug
doctype html
html
head
style
include style.css
body
h1 我的網(wǎng)站
p 歡迎來到我這簡(jiǎn)陋得不能再簡(jiǎn)陋的網(wǎng)站。
script
include script.js
/*style.css*/h1 {
color: red;
}
//script.js
console.log('真了不起!');
文件繼承
【覆蓋】
Pug 支持使用 block 和 extends 關(guān)鍵字進(jìn)行模板的繼承。一個(gè)稱之為“塊”(block)的代碼塊,可以被子模板覆蓋、替換。這個(gè)過程是遞歸的。
Pug 的塊可以提供一份默認(rèn)內(nèi)容,當(dāng)然這是可選的
//- layout.pug
html
head
meta(charset="UTF-8")
title 我的站點(diǎn)-#{title}block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p 一些頁腳的內(nèi)容
現(xiàn)在來擴(kuò)展這個(gè)布局:只需要簡(jiǎn)單地創(chuàng)建一個(gè)新文件,并如下所示用一句 extends 來指出這個(gè)被繼承的模板的路徑。現(xiàn)在可以定義若干個(gè)新的塊來覆蓋父模板里對(duì)應(yīng)的“父塊”。值得注意的是,因?yàn)檫@里的 foot 塊 沒有 被重定義,所以會(huì)依然輸出“一些頁腳的內(nèi)容”
//- pet.pug
p= petName
//- page-a.pug
extends layout.pug
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1=title- var pets = ['貓', '狗']
each petNameinpets
include pet.pug
同樣,也可以覆蓋一個(gè)塊并在其中提供一些新的塊。如下所示,content 塊現(xiàn)在暴露出兩個(gè)新的塊 sidebar 和 primary 用來被擴(kuò)展。當(dāng)然,它的子模板也可以把整個(gè) content 給覆蓋掉
//- sub-layout.pug
extends layout.pug
block content
.sidebar
block sidebar
p 什么都沒有
.primary
block primary
p 什么都沒有
//- page-b.pug
extends sub-layout.pug
block content
.sidebar
block sidebar
p 什么都沒有
.primary
block primary
p 什么都沒有
【擴(kuò)展】
Pug 允許去替換(默認(rèn)的行為)、prepend(向頭部添加內(nèi)容),或者 append(向尾部添加內(nèi)容)一個(gè)塊。 假設(shè)有一份默認(rèn)的腳本要放在 head 塊中,而且希望將它應(yīng)用到 每一個(gè)頁面,可以進(jìn)行如下操作
//- layout.pug
html
head
block head
script(src='/vendor/jquery.js')
script(src='/vendor/caustic.js')
body
block content
現(xiàn)在假設(shè)有一個(gè)頁面,那是一個(gè) JavaScript 編寫的游戲。希望把一些游戲相關(guān)的腳本也像默認(rèn)的那些腳本一樣放進(jìn)去,那么只要簡(jiǎn)單地 append 這個(gè)塊:
//- page.pug
extends layout.pug
block prepend head
script(src='/vendor/three.js')
block append head
script(src='/game.js')
當(dāng)使用 block append 或者 block prepend 時(shí),block 關(guān)鍵字是可省略的:
//- page.pug
extends layout.pug
prepend head
script(src='/vendor/three.js')
append head
script(src='/game.js')
簡(jiǎn)易模板
//- index.pug
doctype html
html
head
meta(charset="UTF-8")
title=documentTitle
each valinsrcStyles
link(href= baseStyle +'/' +val)
body
header.hd
nav.hd-navbar.m-navbar.m-navbar_primary
.hd-navbar-tel 聯(lián)系方式: #{tel}
ul.hd-navbar-nav
each valinmainNavItem
li.Hnn-item.m-btn.m-btn_info
a(href="#")=val
section.main
h1.main-title 我的文檔
p.main-content.
這是一個(gè)很長(zhǎng)很長(zhǎng)而且還很無聊的段落,還沒有結(jié)束,是的,非常非常地長(zhǎng)。
突然出現(xiàn)了一個(gè) #[strong 充滿力量感的單詞],這確實(shí)讓人難以 #[em 忽視]。
footer.ft
p Copyright (c) 小火柴的藍(lán)色理想
each valinsrcScripts
script(src=baseScript + '/' + val)
//- data.json
{"documentTitle":"測(cè)試文檔","tel":"400-888-8888","mainNavItem":['登錄','注冊(cè)','關(guān)于','幫助'],"baseStyle":'style',"srcStyles":['bootstrap.css','main.css'],"baseScript":'/js',"srcScripts":['jquery.js','app.js']
}
總結(jié)
以上是生活随笔為你收集整理的js pug 代码_pug模板引擎(原jade)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: badboy 录制脚本,提示:“当前页面
- 下一篇: monitor java_Java中的m