属性
a(href='baidu.com') 百度
//两个| 代表换行
|
|
a(class='button' href='baidu.com') 百度
|
|
a(class='button', href='baidu.com') 百度
转化为html为
<a href="baidu.com">百度</a>
<a class="button" href="baidu.com">百度</a>
<a class="button" href="baidu.com">百度</a>
多行属性
a(href='./dd.html'
class='a1'
usemap='map1'
) 跳转
转化为html为
<a href='./dd.html' class='a1' usemap='map1'>跳转</a>
也可用模板字面量
a(data-xx=`{'a':'a',
'b':'b',
'c':'c',
}`)
转化为
<a data-xx="
{
"a": "a",
"b": "b",
"c": "c",
}
" />
用括号括起来的属性
//- 在这种情况下,`(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>
<div class="div-class" (click)="play()"></div>
不转义属性
-var a='ddddddd'
//javascript嵌入
//!= 不转义
//模板字面量嵌入
div(class='v'+a,data-d!=`{${a}:'a'}`)
<div class='ddddddd' data-d={
'ddddddd':'a'
}></div>
样式属性
style
(样式)属性可以是一个字符串(就像其他普通的属性一样)还可以是一个对象,这在部分样式是由 JavaScript 生成的情况下非常方便。
a(style={color: 'red', background: 'green'})
<a style="color:red;background:green;"></a>
类属性
class
(类)属性可以是一个字符串(就像其他普通的属性一样)还可以是一个包含多个类名的数组,这在类是由 JavaScript 生成的情况下非常方便。
-var b=['a','b','c']
//class可以是一个将类名映射为 true 或 false 的对象,这在使用条件性的类的时候非常有用。
a(style={width='100px'},class={b:b[2]==='c'}, class=['b'])
<a class='a,b,c,d'></a>
字面量
类字面量
类可以使用 .classname
语法来定义:
a.cl1
<a class='cl1'></a>
id字面量
ID 可以使用 #idname
语法来定义:
a#d
<a id='d'></a>
&attributes
&attributes
语法可以将一个对象转化为一个元素的属性列表。
-var attributes = {};
- attributes.class = 'baz';
//这个对象不一定必须是一个字面值,它同样也可以是一个包含值的对象
div#foo(data-bar="foo")&attributes(attributes)
<div class="baz" id="foo" data-bar="foo"></div>
分支条件
case
是 JavaScript 的 switch
指令的缩写,并且它接受如下的形式:
分支传递
- var friends = 0
case friends
when 0
when 1
p 您的朋友很少
default
p 您有 #{friends} 个朋友
<p>您的朋友很少</p>
块展开
-var friends=10
case friends
when 0: break;
when 1: p(class='dd') ddd
default: p 您有 #{friends} 个朋友
<p>您有10个朋友/p>
代码语法
不输出的代码
用 -
开始一段不直接进行输出的代码,
-
var list = ["Uno", "Dos", "Tres",
"Cuatro", "Cinco", "Seis"]
each item in list
li= item
<li>Uno</li>
<li>Dos</li>
<li>Tres</li>
<li>Cuatro</li>
<li>Cinco</li>
<li>Seis</li>
带输出的代码
用 =
开始一段带有输出的代码,它应该是可以被求值的一个 JavaScript 表达式。为安全起见,它将被 HTML 转义:
p= '这个代码被 <转义> 了!'
<p>这个代码被 <转义> 了!</p>
不转义的、带输出的代码
用 !=
开始一段不转义的,带有输出的代码。这将不会做任何转义,所以用于执行用户的输入将会不安全:
p!= '这段文字' + ' <strong>没有</strong> 被转义!'
<p>这段文字 <strong>没有</strong> 被转义!</p>
注释
带输出的注释和 JavaScript 的单行注释类似,它们像标签,能生成 HTML 注释,而且必须独立一行。
// 一些内容
p foo
p bar
<!-- 一些内容-->
<p>foo</p>
<p>bar</p>
不输出的注释,只需要加上一个横杠。这些内容仅仅会出现在 Pug 模板之中,不会出现在渲染后的 HTML 中。
//- 这行不会出现在结果里
p foo
p bar
<p>foo</p>
<p>bar</p>
条件
Pug 的条件判断的一般形式的括号是可选的,所以您可以省略掉开头的 -
,效果是完全相同的。类似一个常规的 JavaScript 语法形式。
- var user = { description: 'foo bar baz' }
- var authorised = false
#user
if user.description
h2.green 描述
p.description= user.description
else if authorised
h2.blue 描述
p.description.
用户没有添加描述。
不写点什么吗……
else
h2.red 描述
p.description 用户没有描述
<div id="user">
<h2 class="green">描述</h2>
<p class="description">foo bar baz</p>
</div>
Doctype
doctype html
<!DOCTYPE html>
过滤器
过滤器可以让您在 Pug 中使用其他的语言。它们接受传入一个文本块的内容。向过滤器传递参数,只需要将参数如同标签属性一样,放在括号里即可,如::less(ieCompat=false)
所有的 JSTransformer 模块都可以被用作 Pug 的过滤器。有名的过滤器比如 :babel
、:uglify-js
、:scss
和 :markdown-it
。阅读这些 JSTransformer 的文档来了解它们具体支持什么选项。如果您找不到一个您所期望的过滤器,您也可以自己写自定义过滤器。
举一个例子,如果您想要能在您的 Pug 模板中使用 CoffeeScript 语言和 Markdown 语言(使用 Markdown-it 渲染),那么您首先要确定这些东西已经安装好:
$ npm install --save jstransformer-coffee-script
$ npm install --save jstransformer-markdown-it
:markdown-it(linkify langPrefix='highlight-')
# Markdown
Markdown document with http://links.com and
```js
var codeBlocks;
```
script
:coffee-script
console.log 'This is coffee script'
index.pug:1:1
unknown filter ":markdown-it"
包含
包含(include)功能允许您把另外的文件内容插入进来。
//- index.pug
doctype html
html
include includes/head.pug
body
h1 我的网站
p 欢迎来到我这简陋得不能再简陋的网站。
include includes/foot.pug
//- includes/head.pug
head
title 我的网站
script(src='/javascripts/jquery.js')
script(src='/javascripts/app.js')
//- includes/foot.pug
footer#footer
p Copyright (c) foobar
<!DOCTYPE html>
<html>
<head>
<title>我的网站</title>
<script src="/javascripts/jquery.js"></script>
<script src="/javascripts/app.js"></script>
</head>
<body>
<h1>我的网站</h1>
<p>欢迎来到我这简陋得不能再简陋的网站。</p>
<footer id="footer">
<p>Copyright (c) foobar</p>
</footer>
</body>
</html>
被包含的文件的路径,如果是一个绝对路径(如 include /root.pug
),那么前面会加上 options.basedir
选项属性来进行解析。否则,路径应该相对于正在被编译的当前文件。
在 Pug v1 里,如果没有给出文件扩展名,会自动加上 .pug
。但是这个特性在 Pug v2 中这是不赞成使用的。
模板继承
Pug 支持使用 block
和 extends
关键字进行模板的继承。一个称之为“块”(block)的代码块,可以被子模板覆盖、替换。这个过程是递归的。
Pug 的块可以提供一份默认内容,当然这是可选的,见下述 block scripts
、block content
和 block foot
。
//- layout.pug
html
head
title 我的站点 - #{title}
block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p 一些页脚的内容
现在我们来扩展这个布局:只需要简单地创建一个新文件,并如下所示用一句 extends
来指出这个被继承的模板的路径。您现在可以定义若干个新的块来覆盖父模板里对应的“父块”。值得注意的是,因为这里的 foot
块 没有 被重定义,所以会依然输出“一些页脚的内容”。
//- page-a.pug
extends layout.pug
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1= title
- var pets = ['猫', '狗']
each petName in pets
include pet.pug
//- pet.pug
p= petName
同样,也可以覆盖一个块并在其中提供一些新的块。如下面的例子所展示的那样,content
块现在暴露出两个新的块 sidebar
和 primary
用来被扩展。当然,它的子模板也可以把整个 content
给覆盖掉。
块内容的添补 append / prepend
Pug 允许您去替换(默认的行为)、prepend
(向头部添加内容),或者 append
(向尾部添加内容)一个块。 假设您有一份默认的脚本要放在 head
块中,而且希望将它应用到 每一个页面,那么您可以这样做:
//- layout.pug
html
head
block head
script(src='/vendor/jquery.js')
script(src='/vendor/caustic.js')
body
block content
现在假设您有一个页面,那是一个 JavaScript 编写的游戏。您希望把一些游戏相关的脚本也像默认的那些脚本一样放进去,那么您只要简单地 append
这个块:
//- page.pug
extends layout.pug
block append head
script(src='/vendor/three.js')
script(src='/game.js')
当使用 block append
或者 block prepend
时,block
关键字是可省略的
嵌入
字符串嵌入,转义
- var title = "On Dogs: Man's Best Friend";
- var author = "enlore";
- var theGreat = "<span>转义!</span>";
h1= title
p #{author} 笔下源于真情的创作。
p 这是安全的:#{theGreat}
<h1>On Dogs: Man's Best Friend</h1>
<p>enlore 笔下源于真情的创作。</p>
<p>这是安全的:<span>转义!</span></p>
title
被简单地求值;但在 #{
和 }
里面的代码也会被求值,转义,并最终嵌入到模板的渲染输出中。里面可以是任何的正确的 JavaScript 表达式,您可以自由发挥。
如果您需要表示一个 #{
文本,您可以转义它,也可以用嵌入功能来生成(可以,这很元编程)。
字符串嵌入,不转义
使用!{}而不是#{}
标签嵌入
p.
这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。
突然出现了一个 #[strong 充满力量感的单词],这确实让人难以 #[em 忽视]。
p.
使用带属性的嵌入标签的例子:
#[q(lang="es") ¡Hola Mundo!]
<p>这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。
突然出现了一个 <strong>充满力量感的单词</strong>,这确实让人难以 <em>忽视</em>。</p>
<p>使用带属性的嵌入标签的例子:
<q lang="es">¡Hola Mundo!</q></p>
您确实可以在 Pug 中嵌入一行原始 HTML 代码来做同样的事情。但问题是,如何只用 Pug 来做这件事情?将 Pug 的标签语句用 #[
和 ]
括起来就可以了。它会被求值并嵌入到它原来位置的内容中。
空格的调整
标签嵌入功能,在需要嵌入的位置上前后的空格非常关键的时候,就变得非常有用了。因为 Pug 默认会去除一个标签前后的所有空格。
p
| 如果我不用嵌入功能来书写,一些标签比如
strong strong
| 和
em em
| 可能会产生意外的结果。
p.
如果用了嵌入,在 #[strong strong] 和 #[em em] 旁的空格就会让我舒服多了。
<p>如果我不用嵌入功能来书写,一些标签比如<strong>strong</strong>和<em>em</em>可能会产生意外的结果。</p>
<p>如果用了嵌入,在 <strong>strong</strong> 和 <em>em</em> 旁的空格就会让我舒服多了。</p>
迭代
each (for) while
each (for)可以在迭代时获得索引值,能够迭代对象中的键值
- var values = [];
ul
each val,index in values.length ? values : ['没有内容']
li= val
<ul>
<li>没有内容</li>
</ul>
还能添加一个 else
块,这个语句块将会在数组与对象没有可供迭代的值时被执行。
- var n = 0;
ul
while n < 4
li= n++
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
混入(函数)
混入是一种允许您在 Pug 中重复使用一整个代码块的方法。
mixin list
ul
li 1
li 2
li 3
+list
+list
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
混入的块
混入也可以把一整个代码块像内容一样传递进来:
mixin animal(a)
.d
.d
h1=a
if block
block
else
p 没有提供任何内容
+animal(cat)
p 11
p 22
混入的属性
混入也可以隐式地,从“标签属性”得到一个参数 attributes
:
mixin link(href, name)
//- attributes == {class: "btn"}
a(class!=attributes.class href=href)= name
+link('/foo', 'foo')()(class="btn")
<a class="btn" href="/foo">foo</a>
attributes
里的值已经被(作为标签属性)转义了,所以您可能需要用 !=
的方式赋值以避免发生二次转义(详细解释可以查阅不转义的属性)
您也可以直接用 &attributes 方法来传递 attributes
参数:
mixin link(href, name)
a(href=href)&attributes(attributes)= name
+link('/foo', 'foo')()(class="btn")
剩余参数
您可以用剩余参数(rest arguments)语法来表示参数列表最后传入若干个长度不定的参数.
纯文本
Pug 提供了四种方法来放置纯文本,换句话说,任何的代码或者文字都将几乎不经过任何处理,直接输出到 HTML 中。它们在不同的情况下会派上不同的用途。纯文本中依然可以使用标签和字符串的嵌入操作,不过每行开头就不再是 Pug 标签。同样,因为纯文本不经处理,因此您也可以在这里面包含原始 HTML 代码。
原始html
如果一行的开头是左尖括号(<
),那么整行都会被当作纯文本。这在一些书写 HTML 反而更方便的场合下会很有用,一个经典的例子就是条件注释。因为原始 HTML 标签不会被处理,因此它们不像 Pug 的标签,不会自动闭合。
管道文本
另外一种向模板添加纯文本的方法就是在一行前面加一个管道符号(|
),该方法在混合纯文本和行内标签时会很有用.
标签中的纯文本块
有的时候您可能想要写一个非常大的纯文本块。一个典型的例子就是用 script
和 style
内嵌 JavaScript 和 CSS 代码。为此,只需要在标签后面紧接一个点 .
,在标签有属性的时候,则是紧接在闭括号后面。在标签和点之间不要有空格。块内的纯文本内容必须缩进一层.
div
p This text belongs to the paragraph tag.
br
.
This text belongs to the div tag.
<div>
<p>This text belongs to the paragraph tag.</p><br />This text belongs to the div tag.
</div>
空格控制
控制输出 HTML 中的空格,可能是学习 Pug 的过程中最为艰难的部分之一,但别担心,您很快就能掌握它。
关于空格,只需记住两个要点。当编译渲染 HTML 的时候:
- Pug 删掉缩进,以及所有元素间的空格。
- 因此,一个闭标签会紧挨着下一个开标签。这对于块级元素,比如段落,通常不是个问题,因为它们被浏览器分别作为一个一个段落在页面上渲染(除非您改变了它们的 CSS
display
属性)。而当您需要在两个元素间插入空格时,请看下面的方法。
- 因此,一个闭标签会紧挨着下一个开标签。这对于块级元素,比如段落,通常不是个问题,因为它们被浏览器分别作为一个一个段落在页面上渲染(除非您改变了它们的 CSS
- Pug 保留符合以下条件的元素内的空格:
- 一行文本之中所有中间的空格;
- 在块的缩进后的开头的空格;
- 一行末尾的空格;
- 纯文本块、或者连续的管道文本行之间的换行。
因此,Pug 会丢掉标签之间的空格,但保留内部的空格。这将有助于完全掌握应该如何操作标签和纯文本,甚至可以让您在一个单词中间插入一个标签。
标签
在默认情况下,在每行文本的开头(或者紧跟白字符的部分)书写这个 HTML 标签的名称。使用缩进来表示标签间的嵌套关系,这样可以构建一个 HTML 代码的树状结构。
块展开
a:img
<a><img /></a>
目录