テンプレート継承
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`が自動的にファイル名に追加されます。)次に、親ブロックのコンテンツをオーバーライドする1つ以上のブロックを定義します。
下記では、`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
Block `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のテンプレート継承は、複雑なページテンプレート構造をより小さくシンプルなファイルに分割できる強力な機能です。しかし、多くのテンプレートを連鎖させると、自分自身にとって物事をはるかに複雑にする可能性があります。
子テンプレートの最上位(インデントされていない)レベルには、**名前付きブロックとミックスイン定義のみ**が表示されることに注意してください。これは重要です!親テンプレートはページ全体の構造を定義し、子テンプレートは特定のマークアップとロジックのブロックを`append`、`prepend`、または置き換えることしかできません。子テンプレートがブロックの外側にコンテンツを追加しようとすると、Pugは最終ページのどこに配置すればよいかを知る方法がありません。
これには非バッファコードが含まれ、マークアップを含むこともできます。子テンプレートで使用する変数を定義する必要がある場合は、いくつかの異なる方法で行うことができます。
- 変数をPugのoptionsオブジェクトに追加するか、親テンプレートの非バッファコードで定義します。子テンプレートはこれらの変数を継承します。
- 子テンプレートの`block`内で変数を定義します。拡張テンプレートには少なくとも1つのブロックが必要です。そうでなければ空になります—そこで変数を定義してください。
同じ理由で、Pugのバッファされたコメントは拡張テンプレートの最上位レベルに表示できません。それらはHTMLコメントを生成し、結果のHTMLでは配置する場所がありません。(ただし、非バッファのPugコメントはどこにでも配置できます。)