模板继承

Pug 支持模板继承。模板继承通过 blockextends 关键字实现。

在模板中,block 只是一个 Pug “块”,子模板可以替换它。此过程是递归的。

Pug 块可以提供默认内容(如果合适)。不过,提供默认内容完全是可选的。以下示例定义了 block scriptsblock contentblock 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 现在公开了 sidebarprimary 块以供覆盖。(或者,子模板可以完全覆盖 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(默认)、prependappend 块。

假设你在 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 appendblock prepend 时,“block”一词是可选的

//- page.pug
extends layout

append head
  script(src='/vendor/three.js')
  script(src='/game.js')

常见错误

Pug 的模板继承是一个强大的功能,它允许你将复杂的页面模板结构拆分为更小、更简单的文件。但是,如果你将许多、许多模板链接在一起,可能会使事情变得更加复杂。

请注意,只有命名块和 mixin 定义才能出现在子模板的顶部(未缩进)级别。这一点很重要!父模板定义页面的整体结构,而子模板只能 appendprepend 或替换特定的标记和逻辑块。如果子模板尝试在块外部添加内容,Pug 将无法知道在最终页面中将其放在哪里。

这包括无缓冲代码,它也可以包含标记。如果您需要定义变量以便在子模板中使用,您可以通过一些不同的方式来实现

出于同样的原因,Pug 的缓冲注释不能出现在扩展模板的顶层:它们会生成 HTML 注释,而这些注释在生成的 HTML 中无处可去。(然而,无缓冲 Pug 注释仍然可以放在任何地方。)