逻辑语法
以下是关于模板逻辑的语法。
JavaScript代码
不输出的代码
用 - 开始一段不直接进行输出的代码。
1 | - for (var x = 0; x < 3; x++) |
1 | <li>item</li> |
输出的代码
用=开始一段带有输出的代码,它应该是可以被求值的一个JavaScript表达式。为安全起见,它将被HTML转义。1
2
3p
= '这个代码被 <转义> 了!'
p= '这个代码被 <转义> 了!'
1 |
|
不转义的输出代码
用 != 开始一段不转义的,带有输出的代码。这将不会做任何转义,所以用于执行用户的输入将会不安全。
1 | p |
1
2
3<p>这段文字 <strong>没有</strong> 被转义!
</p>
<p>这段文字 <strong>没有</strong> 被转义!</p>
变量
内容变量
使用=或#{}来进行变量的真实值替换。
1 | - var title = "On Dogs: Man's Best Friend"; |
1 | <h1>On Dogs: Man's Best Friend</h1> |
在 #{ 和 } 里面的代码也会被求值、转义,并最终嵌入到模板的渲染输出中。1
2- var msg = "not my inside voice";
p This is #{msg.toUpperCase()}
1 | <p>This is NOT MY INSIDE VOICE</p> |
Pug 足够聪明来分辨到底哪里才是嵌入表达式的结束,所以不用担心表达式中有 },也不需要额外的转义。
1 | p 不要转义 #{'}'}! |
1 | <p>不要转义 }!</p> |
如果需要表示一个 #{ 文本,可以转义它,也可以用嵌入功能来生成。
1 | p Escaping works with \#{interpolation} |
1
2<p>Escaping works with #{interpolation}</p>
<p>Interpolation works with #{interpolation} too!</p>
使用!{}嵌入没有转义的文本进入模板中。
1 | - var riskyBusiness = "<em>我希望通过外籍教师 Peter 找一位英语笔友。</em>"; |
1 | <div class="quote"> |
[注意]如果直接使用用户提供的数据,未进行转义的内容可能会带来安全风险。
属性变量
如果要在属性当中使用变量的话,需要进行如下操作。
1 | - var url = 'pug-test.html'; |
1 | <a href="/pug-test.html">链接</a> |
如果JavaScript运行时支持 ECMAScript 2015 模板字符串,还可以使用下列方式来简化属性值。1
2
3
4
5- 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}`)
1 | <button class="btn btn-info btn-lg" type="button"></button> |
&attributes 语法可以将一个对象转化为一个元素的属性列表。
1 | div#foo(data-bar="foo")&attributes({'data-foo': 'bar'}) |
1 | <div id="foo" data-bar="foo" data-foo="bar"></div> |
变量来源
变量来源有三种,分别是pug文件内部、命令行参数和外部JSON文件。
- pug文件内部
1
2- var val = "测试内容"
p= val
1 | <p>测试内容</p> |
- 命令行参数
使用–obj参数,就可以跟随一个对象形式的参数1
>> $ pug index.pug -w -P --obj '{val:"命令行数据"}
- 外部JSON文件
使用-O,跟随一个JSON文件的路径即可
1 | >> $ pug index.pug -w -P -O test.json |
这三种方式,pug文件内部的变量优先级最多,而外部JSON文件和命令行传参优先级相同。
条件
pug 的条件判断的一般形式的括号是可选的,所以可以省略掉开头的 -,效果完全相同。类似一个常规的 JavaScript 语法形式。
if…else…
1 | - var user = { description: 'foo bar baz' } |
1 | <div id="user"> |
pug 同样也提供了它的反义版本 unless.
1 | - var user = { description: 'foo bar baz', name:'aaa' } |
1 | <p>您已经以 aaa 的身份登录</p> |
switch
case 是 JavaScript 的 switch 指令的缩写,并且它接受如下的形式.
1 | - var friends = 10 |
1 | <p>您有 10 个朋友</p> |
在某些情况下,如果不想输出任何东西的话,可以明确地加上一个原生的 break 语句。1
2
3
4
5
6
7
8- var friends = 0
case friends
when 0
- break
when 1
p 您的朋友很少
default
p 您有 #{friends} 个朋友
循环
pug 目前支持两种主要的迭代方式: each 和 while
each
这是 Pug 的首选迭代方式
1 | ul |
1 | <ul> |
可以在迭代时获得索引值
1 | ul |
1 | <ul> |
能够迭代对象中的键值
1 | ul |
1 | <ul> |
用于迭代的对象或数组仅仅是个 JavaScript 表达式,因此它可以是变量、函数调用的结果,又或者其他
1 | - var values = []; |
1 | <ul> |
还能添加一个 else 块,这个语句块将会在数组与对象没有可供迭代的值时被执行
1 | - var values = []; |
1 | <ul> |
[注意]也可以使用 for 作为 each 的别称
while
也可以使用 while 来创建一个循环
1 | - var n = 0; |
1 | <ul> |
混入
混入是一种允许在 Pug 中重复使用一整个代码块的方法
1 | //- 定义 |
1 | <ul> |
混入可以被编译成函数形式,并传递一些参数
1 | mixin pet(name) |
1 | <ul> |
混入也可以把一整个代码块像内容一样传递进来
1 | mixin article(title) |
1 | <div class="article"> |
混入也可以隐式地,从“标签属性”得到一个参数 attributes1
2
3
4mixin link(href, name)
a(class!=attributes.class href=href)= name
+link('/foo', 'foo')(class="btn")
1 | <a class="btn" href="/foo">foo</a> |
也可以直接用 &attributes 方法来传递 attributes 参数
1 | mixin link(href, name) |
1 | <a class="btn" href="/foo">foo</a> |
可以用剩余参数(rest arguments)语法来表示参数列表最后传入若干个长度不定的参数
1 | mixin list(id, ...items) |
1 | <ul id="my-list"> |
文件包含
包含(include)功能允许把另外的文件内容插入进来
1 | //- index.pug |
被包含的如果不是 pug 文件,那么就只会当作文本内容来引入
文件继承
pug 支持使用 block 和 extends 关键字进行模板的继承。一个称之为“块”(block)的代码块,可以被子模板覆盖、替换。这个过程是递归的。pug 的块可以提供一份默认内容,当然这是可选的。
1 | //- layout.pug |
现在来扩展这个布局:只需要简单地创建一个新文件,并如下所示用一句 extends 来指出这个被继承的模板的路径。现在可以定义若干个新的块来覆盖父模板里对应的“父块”。值得注意的是,因为这里的 foot 块 没有 被重定义,所以会依然输出“一些页脚的内容”
1 | //- pet.pug |
1 | //- page.pug |
1 | //- page-a.pug |
1 | >> $ pug pug-test -w -P //pug-test是存放文件夹 |
1 | <!-- pug-a.html 文件--> |
同样,也可以覆盖一个块并在其中提供一些新的块。如下所示,content 块现在暴露出两个新的块 sidebar 和 primary 用来被扩展。当然,它的子模板也可以把整个 content 给覆盖掉。
1 | //- sub-layout.pug |
1 | //- page-b.pug |
1 | <!-- page-b.html 文件 --> |
扩展
pug 允许去替换(默认的行为)、prepend(向头部添加内容),或者 append(向尾部添加内容)一个块。 假设有一份默认的脚本要放在 head 块中,而且希望将它应用到 每一个页面,可以进行如下操作。
1 | //- layout.pug |
现在假设有一个页面,那是一个 JavaScript 编写的游戏。希望把一些游戏相关的脚本也像默认的那些脚本一样放进去,那么只要简单地 append 这个块:
1 | //- page.pug |
当使用 block append 或者 block prepend 时,block 关键字是可省略的:
1 | //- page.pug |
简易模板
1 | //- index.pug |
1 | //- data.json |