Template Inheritance

更新日: 2018-09-10

継承

テンプレートを継承することができます。 継承はblockextendsを使います。

blockは、単なるブロックです。置き換える内容を指定します。 ブロックは再帰的に置き換えられます。

ブロックは必要に応じて共通ブロックを定義することができます。 例えば以下では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を付与します。)
1以上のブロックを定義して親テンプレートを書き換えます。

以下の例ではblock 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

次の例で示すように、ブロックを上書きすることもできます。 このようにcontentsidebarprimaryを展開してブロックを上書きします。 (または、子テンプレートが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')

appendprependを使う時のblockはオプションです。 つまり、以下のように書くこともできます。

//- page.pug
extends layout

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

よくある間違い

Pugのテンプレート継承は、 複雑なテンプレートを小さく、シンプルなファイルに分割できる大変便利な機能です。 しかし、沢山のテンプレートを連携すると、さらに複雑になってしまいます。

子テンプレートでは、名前付きのブロックとミックスインだけが、 トップレベル(インデントのされていない)に置かれることに注意してください。 これはとても重要です。
親テンプレートはページ全体の構造を定義し、 子テンプレートではappendprependreplaceを使って 特定のブロックのみを変更することになります。 子テンプレートのblockの外側にコンテンツを追加した場合、 そのコンテンツをどこに追加すればよいか判断できません。

OK
//- page-a.pug
extends layout.pug

block scripts
  script(src='/jquery.js')

block content
  h1= title
NG
//- page-a.pug
extends layout.pug

block scripts
  script(src='/jquery.js')

block content
  h1= title

//- トップレベルにはblock,mixin以外のコンテンツ指定不可
h2#subtitlle sub title
div this is NG

非出力処理も同様です。 子テンプレートで使用する変数を定義するには以下の方法があります。

  • オプションを指定するか、 親テンプレートで非出力処理で定義します。
    子テンプレートは定義された変数を継承します。
    //- parent.pug
    - var value = 'title'
    block title
    //- child.pug
    extends parent.pug
    
    block title
      h1 #{value}
    <h1>title</h1>

  • 子テンプレートのブロック内に変数を定義します。
    展開元のテンプレートには最低1つのブロックを作るか、空でも構いません。 そこに変数を定義するだけです。
    //- parent.pug
    block value
    block title
    //- child.pug
    extends block.pug
    
    block value
      - var value = 'title'
    
    block title
      h1 #{value}
    <h1>title</h1>

同じ理由で展開元のテンプレートには表示コメントは HTMLとして生成されません。



© 2017 pugjs.org Released under the MIT license

このコンテンツはpugドキュメントを翻訳/改変したものです。