pug 原名 jade ,因版权问题更名为 pug ,即哈巴狗。与 hexo 默认模块 ejs 一样,pug 也是一个模板引擎,可用于快速的网站开发,当然也可以用于静态博客网站的设计。Pug有它本身的缺点——可移植性差,调试困难,性能并不出色,但使用它可以加快开发效率。
本章目标: 掌握pug样式语法,本章开始我们会从头开始编写自己的博客主题,同样采用pug和styl语法,
一、安装
npm install pug -g
npm install pug-cli -g
二、快速开始
1、新建test.pug文件
html
head
script
style
body
2、执行编译命令
命令行编译
pug -P test.pug
pug -P test.pug --watch
API编译
var jade = require('pug');//加载jade引擎
var fs = require('fs')
//pretty : ture 相当于beauty格式化一下输出的代码
var str = jade.renderFile('test.pug' ,{pretty : true });
fs.writeFile('../build/test.html' ,str , function(err){
if (err)
console.log(err);
else
console.log("编译成功");
})
3、查看生成的html文件
<html>
<head>
<script></script>
<style></style>
</head>
<body></body>
</html>
三、基本语法
pug 不同于 html ,前者不需要标签的开和闭,如 html 的 <p>Demo</p>
,在 pug 使用 p Demo
即可。
1、注释
行注释
//单行注释,会显示在编译后的html代码中
p foo
<!-- 单行注释,会显示在编译后的html代码中-->
//- 单行注释,不会显示在编译后的html代码中
div 单行注释
块注释
块注释注意文本要缩进
body
//-
给模板写的注释
随便写多少字
都没关系。
条件注释
doctype html
<!--[if IE 8]>
<html lang="en" class="lt-ie9">
<![endif]-->
<!--[if gt IE 8]><!-->
<html lang="en">
<!--<![endif]-->
body
p Supporting old web browsers is a pain.
</html>
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="lt-ie9">
<![endif]-->
<!--[if gt IE 8]><!-->
<html lang="en">
<!--<![endif]-->
<body>
<p>Supporting old web browsers is a pain.</p>
</body>
</html>
2、标签
ul
li Item A
<ul>
<li>Item A</li>
</ul>
img
<img />
a: img
<a><img /></a>
//自定义标签
foo/
foo(bar='baz')/
<foo />
<foo bar="baz" />
3、缩进
pug 对空格敏感,有点类似 python 对制表符tab敏感。pug 使用空格作为缩进符,当然用 soft tab 也可行。同一级标签需保证左对齐。
div
p Hello, world!
p Hello, pug.
//render后
<div>
<p>Hellow, world!</p>
<p>Hello, pug.</p>
</div>
4、换行
这是指源文件换行,要用两个 || 来分隔,这样编译后的源码才会有换行,否则会在一行显示
a(href='baidu.com') 百度
|
|
a(class='button' href='baidu.com') 百度
5、属性
pug 将标签属性存放于括号 ()
内,多个属性之间以 逗号
或 空格
分隔。此外,对于标签的 id 和 class ,pug 使用 # 紧跟标签 id
,使用 . 紧跟标签 class
,可以同时设置多个 class 。
h1#title Test title
img#name.class1.class2(src="/test.png" alt="test")
//render后
<h1 id="title">Test title</h1>
<img id="name" class="class1 class2" src="/test.png" alt="test">
//将一个对象转化为一个元素的属性列表
div#foo(data-bar="foo")&attributes({'data-foo': 'bar'})
<div id="foo" data-bar="foo" data-foo="bar"></div>
使用JavaScript 表达式
- var authenticated = true
body(class=authenticated ? 'authed' : 'anon')
//<body class="authed"></body>
- var url = 'pug-test.html';
a(href='/' + url) 链接
//<a href="/pug-test.html">链接</a>
p= '这个代码被 <转义> 了!'
<p>这个代码被 <转义> 了!</p>
p!= '这段文字' + ' <strong>没有</strong> 被转义!'
<p>这段文字 <strong>没有</strong> 被转义!</p>
多行属性
如果您有很多属性,您可以把它们分几行写
input(
type='checkbox'
name='agreement'
checked
)
input(data-json=`
{
"非常": "长的",
"数据": true
}
`)
引号
属性名称中含有某些奇怪的字符,并且可能会与 JavaScript 语法产生冲突的话,请您将它们使用 "" 或者 '' 括起来。您还可以使用逗号来分割不同的属性。
//- 在这种情况下,`(click)` 会被当作函数调用而不是属性名称,这会导致一些稀奇古怪的错误。
div(class='div-class', (click)='play()')
div(class='div-class' '(click)'='play()')
//render后
<div class="div-class" (click)="play()"></div>
<div class="div-class" (click)="play()"></div>
属性转义
在默认情况下,所有的属性都经过转义(即把特殊字符转换成转义序列)来防止诸如跨站脚本attack之类的方式。要使用特殊符号,需要使用!=
而不是 =
。
div(escaped="<code>")
div(unescaped!="<code>")
<div escaped="<code>"></div>
<div unescaped="<code>"></div>
布尔值
input(type='checkbox' checked)
input(type='checkbox' checked=true)
input(type='checkbox' checked=false)
input(type='checkbox' checked=true.toString())
<input type="checkbox" checked="checked" />
<input type="checkbox" checked="checked" />
<input type="checkbox" />
<input type="checkbox" checked="true" />
样式属性
a(style={color: 'red', background: 'green'})
<a style="color:red;background:green;"></a>
- var classes = ['foo', 'bar', 'baz']
a(class=classes)
a.bang(class=classes class=['bing'])
<a class="foo bar baz"></a>
<a class="bang foo bar baz bing"></a>
a.button
<a class="button"></a>
.content
<div class="content"></div> //省略掉的标签是div
a#button
<a id="button"></a>
#content
<div id="content"></div> //省略掉的标签是div
6、定义变量
pug中通过 - var name = value
的形式定义变量,需注意的是,在引用变量时,需要在引用位置加上=号,否则会默认将变量名当成普通字符串使用。
- var intData = 100
- var boolData = false
- var stringData = 'Test'
p.int= intData
p.bool= boolData
p.stringData= stringData
如果想要将变量与其它字符串常量或是变量连接在一起,就不能用等号了,而是应该用 #{} ,该符号会对大括号内的变量进行求值和转义,最终得到渲染输出的内容。
- var girl = 'Lily'
- var boy = 'Jack'
p #{girl} is so beautiful!
p And #{boy} is handsome.
7、逻辑判断
pug中的if else 语句
html
head
body
-var a = 15;
if a%2 == 0
div(style={background:'red'})
else
div(style={background:'green'})
pug中的 switch 语句
- var friends = 10
case friends
when 0
p 您没有朋友
when 1
p 您有一个朋友
default
p 您有 #{friends} 个朋友
<p>您有 10 个朋友</p>
pug 中的each语句
Pug 目前支持两种主要的迭代方式: each 和 while
//- each
ol
each item in ['Sun', 'Mon', 'Tus', 'Wen', 'Thu', 'Fri', 'Sat']
li= item
//- get index of each
- var week = ['Sun', 'Mon', 'Tus', 'Wen', 'Thu', 'Fri', 'Sat']
ol
each item, index in week
li= index + ':' + item
//render后
<ol>
<li>Sun</li>
<li>Mon</li>
<li>Tus</li>
<li>Wen</li>
<li>Thu</li>
<li>Fri</li>
<li>Sat</li>
</ol>
<ol>
<li>0:Sun</li>
<li>1:Mon</li>
<li>2:Tus</li>
<li>3:Wen</li>
<li>4:Thu</li>
<li>5:Fri</li>
<li>6:Sat</li>
</ol>
pug 中的while语句
//- while
- var day = 1
ul
while day < 7
li= day++
8、Minix函数
混入,类似其它编程语言中的函数,也是为了代码复用,可带参数或不带参数,定义方式如下:
mixin menu-item(href, name)
li
span.dot
a(href=href)= name
- menu-item: 为调用时所用名称,可认为是函数名,href 及 name 是参数。a(href=href)= name 中第二个 = 是为了将后面的 name 当作参数来处理,而不是当作字符串 "name" 来处理。
调用 mixin 定义的代码块,需通过 + 号紧跟 mixin 名称及参数
:
+menu-item('/Archives','Archives')
+menu-item('/About','About')
例子如下:
mixin print(post)
if block
block
else
p= post
+print("no block")
+print("")
div.box
p this is the content of block
//renader后
<p>no block</p>
<div class="box"><p>this is the content of block</p></div>
简单的例子
//- 定义
mixin list
ul
li foo
li bar
li baz
//- 使用
+list
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
自定义函数
mixin pet(name)
li.pet= name
ul
+pet('猫')
<ul>
<li class="pet">猫</li>
</ul>
复杂一点的例子
mixin article(title)
.article
.article-wrapper
h1= title
if block
block
else
p 没有提供任何内容。
+article('Hello world')
+article('Hello world')
p 这是我
p 随便写的文章
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>没有提供任何内容。</p>
</div>
</div>
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>这是我</p>
<p>随便写的文章</p>
</div>
</div>
可变参数
mixin list(id, ...items)
ul(id=id)
each item in items
li= item
+list('my-list', 1, 2, 3, 4)
<ul id="my-list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
9、css样式表文件
//-引入内部样式表
style.
#container{
background-color: gray;
}
//-引入外部样式表
link(rel="stylesheet", href="css/my.css")
10、javascript脚本文件
script(type='text/javascript'). //注意第一行的 . 号不要丢
var data = "Test"
var enable = true
if enable
console.log(data)
else
console.log('nothing')
//-引入外部.js文件
script(type='text/javascript', src='/path/to/js')
//- with hexo function url_for
script(type='text/javascript', src=url_for(theme.js) + '/ready.js')
11、文本
字符串嵌入,转义
- 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>
- var msg = "not my inside voice";
p This is #{msg.toUpperCase()}
<p>This is NOT MY INSIDE VOICE</p>
标签嵌入
p.
这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。
突然出现了一个 #[strong 充满力量感的单词],这确实让人难以 #[em 忽视]。
p.
使用带属性的嵌入标签的例子:
#[q(lang="es") ¡Hola Mundo!]
<p>这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。
突然出现了一个 <strong>充满力量感的单词</strong>,这确实让人难以 <em>忽视</em>。</p>
<p>使用带属性的嵌入标签的例子:
<q lang="es">¡Hola Mundo!</q></p>
原始 HTML
如果一行的开头是左尖括号(<),那么整行都会被当作纯文本。
<html>
body
p 缩进 body 标签没有意义,
p 因为 HTML 本身对空格不敏感。
</html>
换行
| 千万别
|
button#self-destruct 按
|
| 我!
千万别
<button id="self-destruct">按</button>
我!
p
| 管道符号总是在最开头,
| 不算前面的缩进。
<p>管道符号总是在最开头,
不算前面的缩进。</p>
三、高级特性
1、继承extends
Pug 支持使用 block 和 extends 关键字进行模板的继承。一个称之为“块”(block)的代码块,可以被子模板覆盖、替换。这个过程是递归的。
定义父模板 layout.pug
html
head
block title
body
block content
定义子模板 page-a.pug
extends layout.pug
block title
title "Test title"
block content
h1 Hello world!
block article
编译后
<html>
<head>
<title>"Test title"</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
块内容的添补 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
//- page.pug
extends layout.pug
block append head
script(src='/vendor/three.js')
script(src='/game.js')
<html>
<head>
<script src="/vendor/jquery.js"></script>
<script src="/vendor/caustic.js"></script>
<script src="/vendor/three.js"></script>
<script src="/game.js"></script>
</head>
<body>
</body>
</html>
2、包含 include
head
title 我的网站
meta(charset='utf-8')
script.
var message = 'hello pug';
window.function(){
// alert(message);
}
html
include head.pug
body
div(id='contaner' class='style1')
包含纯文本
//- index.pug
doctype html
html
head
style
include style.css
body
h1 我的网站
p 欢迎来到我这简陋得不能再简陋的网站。
script
include script.js
/* style.css */
h1 {
color: red;
}
// script.js
console.log('真了不起!');
<!DOCTYPE html>
<html>
<head>
<style>
/* style.css */
h1 {
color: red;
}
</style>
</head>
<body>
<h1>我的网站</h1>
<p>欢迎来到我这简陋得不能再简陋的网站。</p>
<script>
// script.js
console.log('真了不起!');
</script>
</body>
</html>
3、Doctype
下表给出几个例子,其它的还有doctype strict、doctype frameset、doctype 1.1、doctype basic、doctype mobile、doctype plist
源码 | 编译后 |
doctype html |
|
doctype xml |
|
doctype transitional |
|
自定义 doctype
doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN">
五、Hexo相关
1、读取hexo配置文件
在 hexo 主题中使用 pug 时,可以通过使用 hexo 提供的全局变量 config , theme 来分别调用博客根目录下 _config.yml
文件中的参数以及主题根目录下 _config.yml
文件中的参数。pug 中也可以直接使用 hexo 提供的其它全局变量及辅助函数
//- blog config
p= config.description
//- theme config
p= theme.title
标签:Butterfly,Hexo,title,pug,html,var,div,block
From: https://blog.51cto.com/arch/7146612