Edited at

Go 1.6 templateパッケージ新機能

More than 3 years have passed since last update.

Go1.6が2016/02/17にリリースされましたね。

今回はHTTP/2のサポートなどはあるものの、地味なアップデートな印象ですが、個人的に現在作成中のWebサイトでhtml/templateパッケージを使っているので、テンプレート機能の改善に期待をしつつ、試してみました。


Go1.5までの実装

親テンプレートでは{{ template xxx . }}のように、templateで指定します。ここではデフォルト値を入れて、子テンプレートで上書きというよくあるテンプレートエンジンのような利用ができませんでした。


base.gohtml

<!DOCTYPE html>

<html>
<head>
{{ template "head" . }}
</head>
<body>
{{ template "body" . }}
<footer>
{{ template "footer" . }}
</footer>
</body>
</html>

続いて子テンプレートです。{{ define xxx }}で指定します。ただし、例えば下記の例だと、footerは子テンプレートでそもそも指定しないとエラーになりますし、さらに孫テンプレートを作りたいというときに孫で上書きができないという問題がありました。


child.gohtml

{{ define "head" }}

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 以下、略 -->
{{ end }}

{{ define "body" }}
<h1>タイトル</h1>
<!-- 以下、略 -->
{{ end }}

{{ define "footer" }}
{{ end }}



Go1.6からの実装

Go1.6より、親テンプレートにて、{{ block xxx . }}yyyy{{ end }}のように指定することにより、親側でデフォルト実装が定義可能となりました。


base.gohtml

<!DOCTYPE html>

<html>
<head>
{{ block "head" . }}{{ end }}
</head>
<body>
{{ block "body" . }}{{ end }}
<footer>
{{ block "footer" . }}{{ end }}
</footer>
</body>
</html>

親テンプレートでデフォルトが定義されていることにより、子テンプレートでは上書きが必要ない定義の実装が不要になりました。


child.gohtml

{{ define "head" }}

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 以下、略 -->
{{ end }}

{{ define "body" }}
<h1>タイトル</h1>
<!-- 以下、略 -->
{{ end }}


ふむ、地味に便利ですね :smile:

通常はテンプレートを2,3個利用しているケースが大半だと思いますので、こういった改善はうれしいです。

本機能は、text/templateでもhtml/templateでも利用可能です。

そういえば、GoでHTMLのサーバサイドレンダリングの需要がどこまであるのか。。。


スペースのトリム

Go1.6では、RailsのERBなどでもお馴染みのトリム機能も追加されてます。

{{- .title }}のように指定すれば、左側のスペースがトリムされるようになります。

HTMLやテキストのマークアップを美しく保ちたい方にはうれしい機能ですね。


参考