模板继承
Pug 支持模板继承。模板继承通过 block
和 extends
关键字实现。
在模板中,block
只是一个 Pug “块”,子模板可以替换它。此过程是递归的。
Pug 块可以提供默认内容(如果合适)。不过,提供默认内容完全是可选的。以下示例定义了 block scripts
、block content
和 block foot
。
//- layout.pug
html
head
title My Site - #{title}
block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p some footer content
要扩展此布局,请创建一个新文件,并使用 extends
指令指定父模板的路径。(如果未给出文件扩展名,则会自动将 .pug
附加到文件名。)然后,定义一个或多个块来覆盖父块内容。
下面,请注意 foot
块没有重新定义,因此它将使用父块的默认值并输出“some footer content”。
//- page-a.pug
extends layout.pug
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1= title
- var pets = ['cat', 'dog']
each petName in pets
include pet.pug
//- pet.pug
p= petName
还可以覆盖块以提供其他块,如下面的示例所示。如其所示,content
现在公开了 sidebar
和 primary
块以供覆盖。(或者,子模板可以完全覆盖 content
。)
//- sub-layout.pug
extends layout.pug
block content
.sidebar
block sidebar
p nothing
.primary
block primary
p nothing
//- page-b.pug
extends sub-layout.pug
block content
.sidebar
block sidebar
p nothing
.primary
block primary
p nothing
块 append
/ prepend
Pug 允许你 replace
(默认)、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
”一词是可选的
//- page.pug
extends layout
append head
script(src='/vendor/three.js')
script(src='/game.js')
常见错误
Pug 的模板继承是一个强大的功能,它允许你将复杂的页面模板结构拆分为更小、更简单的文件。但是,如果你将许多、许多模板链接在一起,可能会使事情变得更加复杂。
请注意,只有命名块和 mixin 定义才能出现在子模板的顶部(未缩进)级别。这一点很重要!父模板定义页面的整体结构,而子模板只能 append
、prepend
或替换特定的标记和逻辑块。如果子模板尝试在块外部添加内容,Pug 将无法知道在最终页面中将其放在哪里。
这包括无缓冲代码,它也可以包含标记。如果您需要定义变量以便在子模板中使用,您可以通过一些不同的方式来实现
- 将变量添加到 Pug options 对象,或在父模板中的无缓冲代码中定义它们。子模板将继承这些变量。
- 在子模板中的块中定义变量。扩展模板必须至少有一个块,否则它将为空 — 只需在那里定义您的变量即可。
出于同样的原因,Pug 的缓冲注释不能出现在扩展模板的顶层:它们会生成 HTML 注释,而这些注释在生成的 HTML 中无处可去。(然而,无缓冲 Pug 注释仍然可以放在任何地方。)