为了改写 Hexo 模板,学习了 Pug(Jade) ,写一个快速查询手册,方便自己和大家。
本手册不太适合初学者。
Pug 由原来的 Jade 改名为 Pug…
什么是 Pug(Jade) ?
Pug(Jade) 是用来快速构建 HTML 的模板引擎,简单可以理解为用来写 HTML 的。
Pug 的 github Pug 的官网网站
Pug(Jade) 语法
声明语法
1 | doctype html/xml/xhtml |
标签也可以有 id1
div#container
会被转化成
标签也可以有 class1
div.user-details
会被转化成
多个 class,多个 id1
div#foo.bar.baz
会被转换为
语法糖 (便捷语法)1
2#foo
.bar
会被转换为
注释
单行注释
1 | // comments |
块注释
块注释的写法是在 //</code > 后换行并缩进,之后的多行注释内容保持缩进即可,当不需要注释时取消缩进即可
1
2
3
4//
first line comment
second line comment
END
不输出的注释 (Pug 文件的注释,不会被生成 HTML 的一部分)
1 | //- will not output within markup |
会被转换成
1 | <p>foo</p> |
条件注释
1 | body |
嵌套
默认情况下,每行的第一个单词会被认为是 HTML 标签,第二行缩进的单词是子标签。
另外一种情况为嵌套的行内语法,就是在父标签后跟上 :</code > 和空格之后再跟嵌套子标签。
如果想取消嵌套,只能在下一个和嵌套父标签有相同缩进的标签处退出 (需要特别注意),否则整个程序会一层一层嵌套下去
正确的行内嵌套及取消1
2
3
4html
head: title Tag Demo
body
p This is a Tag Demo
错误的行内嵌套及取消1
2
3html: head: title Tag Demo
body
p This is a Tag Demo
自封闭标签
HTML 中的自封闭标签,例如 img
、meta</code > 等,在 Pug(Jade) 中自封闭标签后边紧跟圆括号,在括号中填写标签的参数即可。
1
2img(src="/img.png")
meta(charset="utf-8")
自定义自封闭标签
只需要在标签后加上 /</code > 即可
1
2customized/
customized(id="customized")/
基本属性
在 Pug(Jade) 中,在一个标签后边紧跟上一对圆括号,在圆括号中使用表达式赋值。1
a(href="google.com")
还有一种可以添加属性的方法是使用 &attributes 语法操作属性对象1
p#para&attributes({"A": "a", "B": "b"}) My paragraph.
除此之外还可以定义变量,然后使用标准的 JavaScript 表达式给 Attributes 赋值1
2- var x = 1;
body(id=x==1?1:0)
其中,在 Pug(Jade) 中定义变量使用 - 开头,后边跟一个空格,之后是 JavaScript 声明的变量。
如果一个标签有多个属性,使用逗号分隔1
2
3
4
5
6
7input(id="username",type="text",name="username")
// 甚至可以分开多行来写
input(
id="username",
type="text",
name="username"
) // 和上边效果一样
非转义属性
为了阻止跨站脚本,在默认情况下所有的属性都会被转义,但是如果你真的需要一些特殊字符,比如:<</code > 或 < code>></code > 等,可以使用 < code>!=</code > 替代 < code>=
。1
2div(escaped="<code>")
div(unescaped!="<code>")
布尔属性
Pug(Jade) 可以直接接受 true</code > 和 < code>false</code > 赋值给布尔属性,而且当你缺省赋值时,默认为 < code>true
1
2
3input(type="checkbox",checked)
input(type="checkbox",checked="true")
input(type="checkbox",checked="false")
样式属性
在 style 属性中会有多个值,可以把 style 属性的值看做是一个 JavaScript 对象1
p(style={color:red,font-size:17px})
字面量声明 class 属性和 id 属性
当使用字面量声明 class 和 id 属性时,Pug(Jade) 支持使用 CSS 的类选择器和 id 选择器的方式,这也是最简单的方法。1
2a.commit
a#commit
相当于 HTML 中的:1
2<a class="commit">
<a id="commit">
还可以声明分类。而且对于分类,Pug(Jade) 还有另一种声明方法,就是把分类拆分成数组,然后直接使用数组对 class 属性赋值。1
2
3
4a.commit.first
或
- var classes = ['commit','first'];
a(class=classes)
相当于 HTML 中的:1
<a class="commit first"></a>
&Attributes
Pug(Jade) 提供 & attributes 是为了方便我们将整个对象传递给属性,主要用于为属性整体赋值和将属性穿个 Mixin1
2- var attributes = {'data-foo': 'bar'};
div#foo(data-bar="foo")&attributes(attributes)
相当于 HTML 中:1
<div id="foo" data-bar="foo" data-foo="bar"></div>
转义字符插入
将转义字符写入变量,然后用 #{var}</code > 的方式插入,这种插入方式会将特殊字符串进行转义。
1
2
3
4
5
6
7- var title = "On Dogs: Man's Best Friend";
- var author = "enlore";
- var theGreat = "<span>escape!</span>";
h1= title
p Written with love by #{author}
p This will be safe: #{theGreat}
而且在 #{} 中不仅可以插入变量,其实还可以插入 JavaScript 代码1
2- var msg = "hello world"
p message is #{msg.toUpperCase()}
非转义字符插入
非转义字符串插入和转义字符串插入用法一样,只是使用的是!{},而且在遇到特殊字符是不对其进行转义1
2
3
4
5
6
7- var title = "On Dogs: Man's Best Friend";
- var author = "enlore";
- var theGreat = "<span>escape!</span>";
h1= title
p Written with love by !{author}
p This will be safe: !{theGreat}
HTML 标签插入
标签插入使用的操作符是 #[],在操作符中使用 Pug(Jade) 标签声明代码即可。1
p this is a link #[a(href="http://Pug(Jade).terrynie.com")]
相当于 HTML 中:1
<p>this is a link <a href="http://Pug(Jade).terrynie.com"></a></p>
插入文本
有三种方式:管道符文本 |
、标签行内文本、标签快文本。
管道符文本
管道符出现在每行第一个非空格字符时,该行就会被认为是文本。1
2
3p jade is better than pug
| Plain text can include <strong>html</strong>
p i think
转换成 HTML 为:1
2
3<p>jade is better than pug</p>
Plain text can include <strong>html</strong>
<p>i think</p>
标签行内文本
将文本放在标签之后,并用空格与标签隔开即可。1
p this is a inline text in a tag
相当于 HTML 中:1
<p>this is a inline text in a tag</p>
标签块文本
在 script</code > 或 < code>style</code > 标签的后面紧跟 < code>.</code > 即可(不能有空格)
1
2
3
4
5script.
if (usingPug(Jade))
console.log('you are awesome')
else
console.log('use Pug(Jade)')
Block
在 Pug(Jade) 中,允许使用 block
结合 extends
关键字预定义一个模板供其他模板调用。调用时,如果父模板中定义了某块内容,而子模板中没有定义时,默认显示父模板中的内容。 Pug(Jade) 通过这种方法实现模板的继承和重用。
除了继承模板,还可以使用 append 和 prepend 对继承的模板进行扩展。
模板继承
block
的声明方式1
2block blockName
content
举例
在 layout.Pug(Jade)
中的 head
中定义一个 block
,名称为 scripts
,默认内容为 script(src='/jquery.js')
,在 body
中定义一个 block
,名称为 content
,默认内容为空。
在 page.Pug(Jade)
中用 extends
继承 layout.Pug(Jade)
模板,并且重新定义名为 scripts
的 block
。
layout.Pug(Jade)1
2
3
4
5
6
7
8- var title = 'blog'
html
head
title My Site - #{title}
block scripts
script(src='/jquery.js')
body
block content
page.Pug(Jade)1
2
3
4extends ./layout.Pug(Jade)
block scripts
script(src='/bootstrap.js')
生成的 HTML 文件:1
2
3
4
5
6
7
8
9<html>
<head>
<title>My Site - blog</title>
<script src="/bootstrap.js"></script>
</head>
<body>
<h1>title</h1>
</body>
</html>
在 page.Pug(Jade)
中使用 extends
继承了 layout.Pug(Jade)
,并且默认覆盖了 layout.Pug(Jade)
中的 block scripts
,但是没有指定 block content
的内容,所以 block content
中还是 layout.Pug(Jade)
中的内容。
Block Append & Block Prepend
append
可以在父模板中的 block
内容后面追加内容
举例,继承 layout.Pug(Jade) 文件,然后在名为 scripts
的 block
内容后面追加内容 script(src='/bootstrap.js')
。1
2
3extends ./layout.Pug(Jade)
block append scripts
script(src='/bootstrap.js')
转换成 HTML 文件为:1
2
3
4
5
6
7
8
9<html>
<head>
<title>My Site - blog</title>
<script src="/jquery.js"></script>
<script src="/bootstrap.js"></script>
</head>
<body>
</body>
</html>
prepend
可以在父模板中的 block
内容前面添加内容
举例,继承 layout.Pug(Jade) 文件,然后在名为 scripts
的 block
内容前面追加内容 script(src='/bootstrap.js')
。1
2
3extends ./layout.Pug(Jade)
block prepend scripts
script(src='/bootstrap.js')
转换成 HTML 文件为:1
2
3
4
5
6
7
8
9<html>
<head>
<title>My Site - blog</title>
<script src="/bootstrap.js"></script>
<script src="/jquery.js"></script>
</head>
<body>
</body>
</html>
在使用 block append
和 block prepend
时, block
是可选的,简写形式可将其省略。
省略之后的命令为:1
2
3
4
5append scripts
script(src='/bootstrap.js')
和
prepend scripts
script(src='/bootstrap.js')
Includes
引入 Pug(Jade) 文件
Includes
是代码复用的另一种方式,允许你将一个 Pug(Jade)
文件中的内容引入到另一个 Pug(Jade)
文件中。
举例,创建两个名为 head.Pug(Jade)
和 footer.Pug(Jade)
的文件,并在 page.Pug(Jade)
文件中使用 includes
命令,来引入两个文件中的内容。
head.Pug(Jade)1
2head
title This is head
footer.Pug(Jade)1
footer this is a footer
page.Pug(Jade)1
2
3
4
5html
include ./head.Pug(Jade)
body
h1 this is a include demo
include ./footer.Pug(Jade)
生成的 HTML 文件为:1
2
3
4
5
6
7
8
9<html>
<head>
<title>This is head</title>
</head>
<body>
<h1>this is a include demo</h1>
<footer>this is a footer</footer>
</body>
</html>
引入文本文件
除了可以使用 includes
引入 Pug(Jade) 文件,还可以使用它引入文本文件,比如 CSS 或 JavaScript 脚本文件。引入样式文件和脚本文件时,文件内容被作为纯文本引入到 Pug(Jade) 文件中。注意引入 CSS 和 JavaScript 这两类文件之前,要先分别加入声明 style
和 script
,这样转换出来的 HTML 文件才能正确被浏览器编译。
举例,创建一个名为 style.css 的文件和一个名为 script.js 的文件,然后在 index.Pug(Jade) 中引入这两个文件,并且转换为 HTML 文件。
style.css1
h1 {color: red;}
script.js1
console.log('You are awesome');
index.Pug(Jade)1
2
3
4
5
6
7
8
9
10doctype html
html
head
style
include style.css
body
h1 My Site
p Welcome to my super lame site.
script
include script.js
转换成 HTML 为:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<style>
h1 {color: red;}
</style>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to my super lame site.</p>
<script>
console.log('You are awesome');
</script>
</body>
</html>
过滤器
过滤器允许你在 Pug(Jade) 模板中使用其他语言,然后 Pug(Jade) 自动调用所需的解释器进行转换。所使用的符号就是 :
并在分号后加上使用的语言名称,目前支持的过滤器有以下几种:
| 语言名称 | 需要安装 |
|-|-|
|sass|sass.js|
|less|less.js|
|markdown|markdown-js 或 node-discount|
|cdata|/|
|coffeescript|coffee-script|
举例1
2
3
4
5
6
7:markdown
# Markdown
I often like including markdown documents.
script
:coffee-script
console.log 'This is coffee script'
转化成 HTML 为1
2
3<h1>Markdown</h1>
<p>I often like including markdown documents.</p>
<script>console.log('This is coffee script')</script>
循环
Pug(Jade) 支持两种主要的循环:each 和 while。另外还有一个 for ,用法和 each 相同。
each
通过 each 迭代器可以快速迭代数组和对象,并且可以获取数组的索引和对象的键:
each.Pug(Jade):
ul
each val,idx in [1, 2, 3, 4, 5]
li #{val} is at #{idx}
each.html:
- 1 is at 0
- 2 is at 1
- 3 is at 2
- 4 is at 3
- 5 is at 4
上面的例子只是简单的迭代获取数组中的内容,下面的这个例子将同时获取数组的索引和对应的内容:
each2.Pug(Jade):
ul
each val, index in [‘zero’, ‘one’, ‘two’]
li= index + ‘:’ + val
each2.html:
- 0: zero
- 1: one
- 2: two
在免费送一个同时获取对象中键和值得例子吧:
each3.Pug(Jade):
ul
each val, index in {1:’one’,2:’two’,3:’three’}
li= index + ‘:’ + val
each3.html:
- 1: one
- 2: two
- 3: three
同样,上边的几个例子中的 each 完全可以可以使用 for 来替换,for 可以被作为 each 的别名来使用。
while
除了使用 each 之外还有就是可以使用 while 来循环,用法也很简单。
while.Pug(Jade):
- var n = 0
ul
while n < 4
li= n++
while.html:- 0
- 1
- 2
- 3
这就是 while 的用法,和其他语言的使用方法几乎都是一样的。
Mixin
在Pug(Jade)中,除了前面讲的两种代码反复用方式:extends和includes之外,还有一个更加强大且常用的方式,那就是本节要讲的Mixin。Mixin更像一个函数,可以是无参的,也可以是有参的,定义之后只需要在希望使用它的地方调用即可,方便得很。