Hugo のテンプレートファイル内で define
を使用すると、部分的なテンプレートを定義することができ、別の場所から関数のように呼び出すことができます。
define による部分テンプレート定義の基本
Hugo のテンプレート定義は、基本は layouts
ディレクトリ内に置いたテンプレートファイル(HTML ファイル)単位で行うのですが、そのテンプレートファイルの中で、define
アクションを使用することで、入れ子でテンプレート定義を行うことができます。
テンプレートファイル内で使える関数定義のようなもの だと思うと分かりやすいです。
次の例では、define
を使用して、showParentSection
というテンプレートを定義しています。
define
で定義したテンプレートを呼び出すには、template
関数を使用します。
{{ template "showParentSection" . }}
2 番目のパラメータで渡した値が、部分テンプレート側のドットコンテキスト (.
) として参照できるようになります。
多くの場合は、上記のようにドット (.
) を指定し、Page
オブジェクトを参照できるようにします。
複数のパラメータを受け取る部分テンプレートを定義する
template
関数を使って部分テンプレートを呼び出すときは、引数に .
を指定して Page
オブジェクトを渡すことが多いのですが、単純な文字列や数値をパラメータとして渡すこともできます。
次の例では、パラメータで渡された名前を使って挨拶文を出力する greet
テンプレートを定義しています。
この greet
テンプレートを呼び出すには次のようにします。
{{ template "greet" "Maku" }}
パラメータとして マップオブジェクト を渡せば、名前付きパラメータを実現できます。
次の例で定義している calc
テンプレートは、x
と y
というキーを含むマップオブジェクトを受け取ることを想定しています。
{{ define "calc" }}
{{ printf "%d+%d=%d" .x .y (add .x .y) }}
{{ end }}
この calc
テンプレートは次のように呼び出します。
マップオブジェクトを作成するときは、dict
関数のパラメータに、キーと値を交互に指定します。
{{ template "calc" (dict "x" 100 "y" 200) }}
マップオブジェクトを受け取る部分テンプレートを定義するときは、次のように先頭でローカル変数($x
や $y
)に代入してしまう慣例もあるようです。
このように記述しておくことで、この部分テンプレートにどのようなキーを持つマップオブジェクトを渡せばよいのかが一目で分かるようになります。
{{ define "calc" }}
{{ $x := .x }}
{{ $y := .y }}
{{ printf "%d+%d=%d" $x $y (add $x $y) }}
{{ end }}
パーシャルテンプレートとの違い
layouts/partials/foo.html
というファイル名で作成したパーシャルテンプレートは、次のように partial
を使って呼び出します。
{{ partial "foo" . }}
一方で、define
で定義した部分テンプレート(Go のドキュメントでは nested template と呼んでいます)は、次のように template
を使って呼び出します。
{{ template "foo" . }}
呼び出し方がちょっと異なるだけで、ほとんど同じような感覚で使えるようです。 使い分けの基準としては、
- 複数のテンプレートファイルから共通で使用するものは、パーシャルテンプレート (
layouts/partials/xxx.html
) として定義する。 - 1 つのテンプレートファイル内でのみ使用する部分テンプレートは、
define
による部分テンプレートとして定義する。
と考えておけばよいでしょう。