Hugoで
共通のコードはなるべく書かない。一箇所にまとめる(DRY)
という方針を進めるためにはどうしたらよいか。自分なりのひとつの答え。
- single.html や section.html など直接テンプレートとして用いられるHTMLファイルの名前空間(
.
)は{{template}}
を呼び出すときに .Config という名前で参照できるようにpipelineに辞書(dict)を渡す- これにより
{{define}}
の中や partial HTMLの中では共通して{{.Config.Site.Title}}
などの名前でアクセスできる - またこの辞書には .Title というページタイトルや .Description というページ概要を含む
- 例:
{{template "hoge" (dict "Config" . "Title" .Title "Description" .Description)}}
- Config … テンプレートHTMLの名前空間全体
.
- Title … ページコンテンツで定義されている
.Title
- Description … ページコンテンツで定義されている
.Description
- Config … テンプレートHTMLの名前空間全体
- HTMLファイルの先頭でこの辞書を $pipeline などの変数に入れておくと全ての
{{template}}
呼び出しで使い回せる {{define}}
や partial の中からさらに{{template}}
を呼び出す場合は単に名前空間(.
)を継承するか、(dict "Config" .Config)
などのように Config が引き継がれるようにする
- これにより
- page-template.html に汎用的なページ構成とそこで用いるパーツを定義(
{{define}}
)する{{define "html-header"}}
… <html>〜<body> までのHTMLヘッダ{{define "page-header"}}
… 全ページ共通のヘッダ部分{{define "navigation"}}
… 一部のページで共通して含むナビゲーションバー{{define "page-footer"}}
… 全ページ共通のフッタ部分{{define "html-footer"}}
… HTMLフッタ </body></html>- また、コンテンツページで共通して使う部分をさらに簡易化定義している
{{define "common-header"}}
… 共通ヘッダ"html-header"
+"page-header"
+"navigation"
{{define "common-footer"}}
… 共通フッタ"page-footer"
+"html-footer"
- トップページ index.html はナビゲーションバーが必要ないので
"html-header"
と"page-header"
ならびに"page-footer"
"html-footer"
だけを呼び出す- また、ページタイトルは不要なので $pipeline 辞書に Title を含まない
- デフォルトの single.html は
共通ヘッダ表示、コンテンツ表示、共通フッタ表示だけを行うシンプルなものとなる
{{define}}
に含まれない地の部分では .Config.Content ではなく .Content のような名前で変数を参照する
- セクション固有の single.html (例)は
デフォルトの single.html と同様の構成で固有の表示を作れる
- このとき共通部分(HTMLヘッダ〜ページヘッダ〜ナビゲーションバー、ページフッタ〜HTMLフッタ)は
{{template}}
呼び出しだけなのでDRYに反するようなコードの再記述は必要ない
- このとき共通部分(HTMLヘッダ〜ページヘッダ〜ナビゲーションバー、ページフッタ〜HTMLフッタ)は
- デフォルトのリスト表示 section.html も
デフォルトの single.html に似た構成だが、
セクションリストの表示方法を
{{define "section-list"}}
として定義している- 定義した
"section-list"
を直後にすぐ{{template "section-list" $pipeline}}
と呼び出す - 1件1件の表示自体も定義したり partial にしたほうが汎用性が高まる(今回はシンプルにするためそこまではしていない)
- 定義した
- セクション固有の section.html にあたる section/SECTION.html(例)は
デフォルトの section.html で定義した
"section-list"
を用いて リスト表示する部分は再記述することなく固有の表示も実現できる
- partial HTML はパーツだけを個々のHTMLファイルにして
{{partial}}
で呼び出す {{define}}
で定義したパーツは layouts 配下のどこに配置してもよく、{{template}}
で呼び出す- 名前空間(pipeline)の指定については変わりがない(と思われる)
- だったらファイルをバラバラと分けずひとつのHTMLやデフォルトのテンプレートの中に
{{define}}
定義を置けたほうがいんでね?と思う次第