Pug模板 #
一、Pug简介 #
1.1 什么是Pug? #
Pug(原名Jade)是一个高性能的模板引擎,使用缩进来表示嵌套关系,语法简洁优雅。
1.2 特点 #
- 缩进式语法,无需闭合标签
- 支持模板继承
- 支持Mixins
- 可扩展性强
1.3 安装 #
bash
npm install pug
二、基本配置 #
2.1 设置视图引擎 #
javascript
const express = require('express');
const app = express();
app.set('view engine', 'pug');
app.set('views', './views');
三、Pug语法 #
3.1 标签 #
pug
html
head
title 页面标题
body
h1 标题
p 段落内容
编译为:
html
<html>
<head>
<title>页面标题</title>
</head>
<body>
<h1>标题</h1>
<p>段落内容</p>
</body>
</html>
3.2 属性 #
pug
a(href='/home', class='link', target='_blank') 首页
input(type='text', name='username', placeholder='用户名')
div#main.container.active
编译为:
html
<a href="/home" class="link" target="_blank">首页</a>
<input type="text" name="username" placeholder="用户名">
<div id="main" class="container active"></div>
3.3 文本 #
pug
p 普通文本
p.
多行文本
第二行
第三行
p
| 文本行1
| 文本行2
strong 加粗文本
3.4 变量输出 #
pug
h1= title
p= message
p 欢迎, #{user.name}
p 年龄: #{user.age || '未知'}
3.5 属性中使用变量 #
pug
a(href=url) 链接
a(href='/user/' + userId) 用户详情
input(value=defaultValue)
div(class=isActive ? 'active' : 'inactive')
四、条件语句 #
4.1 if/else #
pug
if user
p 欢迎, #{user.name}
else
p 请登录
if user.role === 'admin'
p 管理员面板
else if user.role === 'editor'
p 编辑面板
else
p 用户面板
4.2 unless #
pug
unless user
p 请先登录
4.3 case #
pug
case status
when 'active'
p 激活
when 'inactive'
p 未激活
default
p 未知状态
五、循环语句 #
5.1 each #
pug
ul
each user in users
li= user.name
each user, index in users
p #{index + 1}. #{user.name}
5.2 for #
pug
- for (let i = 0; i < items.length; i++)
p= items[i]
5.3 while #
pug
- let n = 0
while n < 5
p= n++
六、代码 #
6.1 单行代码 #
pug
- const name = '张三'
- const age = 25
p= name
6.2 多行代码 #
pug
-
const users = [
{ name: '张三', age: 25 },
{ name: '李四', age: 30 }
]
const total = users.length
七、包含文件 #
7.1 include #
pug
include header.pug
include partials/nav.pug
main
h1 内容区域
include footer.pug
7.2 包含其他类型文件 #
pug
style
include style.css
script
include script.js
八、模板继承 #
8.1 定义布局 #
views/layout.pug:
pug
doctype html
html
head
title= title
block head
body
include partials/header
block content
include partials/footer
block scripts
8.2 继承布局 #
views/index.pug:
pug
extends layout
block head
link(rel='stylesheet', href='/css/home.css')
block content
h1 首页
p 欢迎来到网站
block scripts
script(src='/js/home.js')
8.3 追加/前置 #
pug
extends layout
block append head
link(rel='stylesheet', href='/css/custom.css')
block prepend scripts
script(src='/js/common.js')
九、Mixins #
9.1 定义Mixin #
pug
mixin userCard(user)
.user-card
h3= user.name
p= user.email
span= user.role
9.2 使用Mixin #
pug
each user in users
+userCard(user)
9.3 带属性的Mixin #
pug
mixin link(href, name)
a(href=href)&attributes(attributes)= name
+link('/home', '首页')
+link('/about', '关于')(class='nav-link', target='_blank')
9.4 块级Mixin #
pug
mixin article(title)
article
h2= title
if block
block
else
p 无内容
+article('标题')
p 这是文章内容
十、完整示例 #
10.1 布局文件 #
views/layout.pug:
pug
doctype html
html(lang='zh-CN')
head
meta(charset='UTF-8')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
title= title + ' - ' + siteName
link(href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css', rel='stylesheet')
block styles
body
nav.navbar.navbar-expand-lg.navbar-dark.bg-dark
.container
a.navbar-brand(href='/')= siteName
.navbar-collapse
ul.navbar-nav
li.nav-item
a.nav-link(href='/') 首页
li.nav-item
a.nav-link(href='/users') 用户
li.nav-item
a.nav-link(href='/posts') 文章
.container.mt-4
if messages.error
.alert.alert-danger= messages.error
if messages.success
.alert.alert-success= messages.success
block content
footer.bg-dark.text-light.py-4.mt-5
.container.text-center
p © 2024 #{siteName}
script(src='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js')
block scripts
10.2 用户列表页面 #
views/users/index.pug:
pug
extends ../layout
block content
.d-flex.justify-content-between.align-items-center.mb-4
h2 用户列表
a.btn.btn-primary(href='/users/new') 添加用户
table.table.table-striped
thead
tr
th ID
th 用户名
th 邮箱
th 角色
th 创建时间
th 操作
tbody
each user in users
tr
td= user.id
td= user.name
td= user.email
td
span.badge(class=user.role === 'admin' ? 'bg-danger' : 'bg-primary')= user.role
td= formatDate(user.createdAt)
td
a.btn.btn-sm.btn-info(href='/users/' + user.id) 查看
a.btn.btn-sm.btn-warning(href='/users/' + user.id + '/edit') 编辑
form.d-inline(action='/users/' + user.id + '?_method=DELETE', method='POST')
button.btn.btn-sm.btn-danger(type='submit', onclick='return confirm("确定删除?")') 删除
if totalPages > 1
nav
ul.pagination.justify-content-center
if currentPage > 1
li.page-item
a.page-link(href='/users?page=' + (currentPage - 1)) 上一页
- for (let i = 1; i <= totalPages; i++)
li.page-item(class=currentPage === i ? 'active' : '')
a.page-link(href='/users?page=' + i)= i
if currentPage < totalPages
li.page-item
a.page-link(href='/users?page=' + (currentPage + 1)) 下一页
10.3 Mixins文件 #
views/mixins/user.pug:
pug
mixin userCard(user)
.card.mb-3
.card-body
h5.card-title= user.name
h6.card-subtitle.mb-2.text-muted= user.email
p.card-text
span.badge.bg-primary= user.role
a.card-link(href='/users/' + user.id) 查看详情
mixin pagination(currentPage, totalPages, baseUrl)
if totalPages > 1
nav
ul.pagination.justify-content-center
if currentPage > 1
li.page-item
a.page-link(href=baseUrl + '?page=' + (currentPage - 1)) 上一页
- for (let i = 1; i <= totalPages; i++)
li.page-item(class=currentPage === i ? 'active' : '')
a.page-link(href=baseUrl + '?page=' + i)= i
if currentPage < totalPages
li.page-item
a.page-link(href=baseUrl + '?page=' + (currentPage + 1)) 下一页
10.4 使用Mixins #
pug
include mixins/user
extends layout
block content
h2 用户卡片
each user in users
+userCard(user)
+pagination(currentPage, totalPages, '/users')
十一、总结 #
Pug要点:
| 语法 | 说明 |
|---|---|
| 缩进 | 表示嵌套关系 |
| = | 输出变量 |
| #{} | 插值输出 |
| extends | 继承模板 |
| block | 定义区块 |
| include | 包含文件 |
| mixin | 定义可复用块 |
下一步,让我们学习静态文件服务!
最后更新:2026-03-28