pug模板引擎(上)

安装

sudo npm install pug

但命令行提示 pug 命令未找到,接下来安装 pug-cli,注意一定要全局安装,否则无法正常编译。

sudo npm install pug-cli -g

查看版本

>>> $ pug --version
pug version: 2.0.3
pug-cli version: 1.0.0-alpha6

生成HTML

新建文件命名为index.pug

html
    head
        title dp2px
    body

在命令行输入

>>> $ pug index.pug 
rendered index.html

你会发现在同目录生成了一个 index.html 文件,内容如下

<html><head><title>dp2px</title></head><body></body></html>

接下来我们使用pug -w实现自动编译。

>>> $ pug index.pug -w

我使用的 VS Code,你可以让你的编辑器左右两边显示,方便实时查看。

pug

但是我们发现上面生成的 html 不是标准格式,如果要显示标准格式而不是压缩版就要使用另一个参数了。

>>> $ pug index.html -P 

你可以自动编译的同时使用标准格式

>>> $ pug index.pug -w -P

如果不希望在当前目录下生成 html 可以自定义输出路径。

>>> $ pug index.pug -o newpath/newpath

如果希望修改生成的文件名可以使用下面方式生成

>>> $ pug path/index.pug newpath/newindex.html

批量编译,例如批量编译 dir 目录下的 pug 文件

>>> $ pug dir

结构语法

标签

树状

在默认情况下,在每行文本的开头(或者紧跟白字符的部分)书写这个 HTML 标签的名称。使用缩进来表示标签间的嵌套关系,这样可以构建一个 HTML 代码的树状结构。

注意:后面默认上面是 pug 文件内容,下面紧跟着是对应生成的 html 文件内容。

ul				
    li			
    li
    li

生成后

<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

内联

为了节省空间,pug 嵌套标签提供了一种内联语法。

a: img

生成后

<a><img/></a>

自闭合

pug知道哪些元素是自闭合的,也可以通过在标签后加上 / 来明确声明此标签是自闭合的。

img
input
img/
input/

生成后

<img/>
<input/><img/>
<input/>

DOCTYPE

HTML5 的 DOCTYPE 书写如下

doctype html

生成后

<!DOCTYPE html>

内容

pug 提供了三种常用的方式来放置内容。

管道文本

这是最简单的向模板添加纯文本的方法。只需要在每行前面加一个 | 字符,这个字符在类 Unix 系统下常用作“管道”功能,因此得名。

p: span|dfdfdfdfd

生成后

<p><span>dfdfdfdfd</span></p>

标签内文本

这实际上是最常见的情况,文本只需要和标签名隔开一个空格即可。

p: span dfdfdfdfd

生成后

<p><span>dfdfdfdfd</span></p>

嵌入大段文本

有时可能想要写一个大段文本块。比如嵌入脚本或者样式。只需在标签后面接一个 . 即可。

script.
    if(usingPug){
        console.log("使用了pug")
    }else{
        console.log("请使用pug")
    }

生成后

<script>
  if(usingPug){
      console.log("使用了pug")
  }else{
      console.log("请使用pug")
  }
</script>

属性

标签属性和 HTML 语法非常相似,它们的值就是普通的 JavaScript 表达式。可以用逗号或空格作为属性分隔符。

a(href='baidu.com') 百度
= '\n'
a(class='button', href="baidu.com") baidu

生成后

<a href="baidu.com">百度</a>
<a class="button" href="baidu.com">baidu</a>

多行属性

如果有很多属性,可以把它们分几行写。

input(
  type='checkbox'
  name='agreement'
  checked
)

生成后

<input type="checkbox" name="agreement" checked="checked"/>

长属性

如果有一个很长的属性,并且 JavaScript 运行时引擎支持 ES2015 模板字符串,可以使用它来写属性值。

input(data-json='
  {
    "非常": "长的",
    "数据": true
  }
')

生成后


<input data-json="
  {
    &quot;非常&quot;: &quot;长的&quot;,
    &quot;数据&quot;: true
  }
"/>

特殊字符

如果属性名称中含有某些奇怪的字符,可能会与 JavaScript 语法产生冲突的话,可以将它们使用 “” 或者 “ 括起来。还可以使用逗号来分割不同的属性。

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>

转义属性

默认情况下,所有的属性都经过转义(即把特殊字符转换成转义序列)来防止诸如跨站脚本攻击之类的攻击方式。如果要使用特殊符号,需要使用 != 而不是 =.

[注意]未经转义的缓存代码十分危险。必须正确处理和过滤用户的输入来避免跨站脚本攻击。

div(escaped="<code>")
div(unescaped!="<code>")

生成后

<div escaped="&lt;code&gt;"></div>
<div unescaped="<code>"></div>

布尔值

在pug中,布尔值属性是经过映射的,这样布尔值(true 和 false)就能接受了。没有指定值时,默认是 true。

input(type='checkbox' checked)
= '\n'
input(type='checkbox' checked=true)
= '\n'
input(type='checkbox' checked=false)
= '\n'
input(type='checkbox' checked=true.toString())

生成后

<input type="checkbox" checked="checked"/>

<input type="checkbox" checked="checked"/>

<input type="checkbox"/>

<input type="checkbox" checked="true"/>

行内样式

style(样式)属性可以是一个字符串(就像其他普通的属性一样)还可以是一个对象。

a(style={color: 'red', background: 'green'})

生成后

<a style="color:red;background:green;"></a>

类和ID

类可以使用 .classname 语法来定义,ID 可以使用 #idname 语法来定义。

考虑到使用 div 作为标签名这种行为实在是太常见了,所以如果省略掉标签名称的话,它就是默认值。

a.button
.content
="\n"
a#main-link
#content

生成后

<a class="button"></a>
<div class="content"></div>
<a id="main-link"></a>
<div id="content"></div>

标签嵌入

标签支持一种标签嵌入的写法,形式如下。

#[标签名(标签属性)  标签内容]

对于内联标签来说,这种写法比较简单,例如。

p.
  这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。
  突然出现了一个 #[strong 充满力量感的单词],这确实让人难以 #[em 忽视]。

生成后

<p>
  这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。
  突然出现了一个 <strong>充满力量感的单词</strong>,这确实让人难以 <em>忽视</em>。
</p>

空格调整

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>

注释

单行注释

单行注释和 JavaScript 类似,但是必须独立一行。

// 一些内容
p foo
p bar

生成后

<!-- 一些内容-->
<p>foo</p>
<p>bar</p>

不输出注释

只需要加上一个横杠,就可以使用不输出注释。

//- 这行不会出现在结果里
p foo
p bar

块注释

body
  //
    随便写多少字
    都没关系。

生成后

<body>
  <!--
  随便写多少字
  都没关系。
  -->
</body>

条件注释

pug 没有特殊的语法来表示条件注释(conditional comments)。不过因为所有以 < 开头的行都会被当作纯文本,因此直接写一个 HTML 风格的条件注释也是没问题的。

<!--[if IE 8]>
<html lang="en" class="lt-ie9">
<![endif]-->
<!--[if gt IE 8]><!-->
<html lang="en">
<!--<![endif]-->