テンプレートで変数の出力について詳しく解説

こんにちはnasustです。

Hugoのテンプレートで変数を出力する{{ $variable }}について詳しく解説します。

HTMLの出力

一番使用されるHTMLの変数出力です。 変数の内容は、HTMLエスケープされます。

{{ $variable := "abc&def" }}
{{ $variable }}
<!-- 結果: abc&amp;def -->

HTMLのエスケープされたく無い場合

{{ $variable := "abc&def" }}
{{ $variable | safeHTML }}
<!-- 結果: abc&def -->

HTMLタグの属性

HTMLタグの属性に変数を出力する場合は同じ様に記述します。 属性用にエスケープしてくれます。

{{ $variable := "https://nasust.com" }}
<a href="{{ $variable }}">alert link</a>
<!-- 結果: <a href="https://nasust.com">alert link</a> -->

属性の値がセキュリティの問題になりそうな場合

HTMLの変数出力と同じ様にしてもエラーになります。

{{ $variable := "javascript:alert('Hello');" }}
<a href="{{ $variable }}">alert link</a>
<!-- 結果: <a href="#ZgotmplZ">alert link</a> -->

これはHugoを実装しているGo言語のtemplateの機能で、問題になる箇所は#ZgotmplZと出力されます。 以下の文章はGoのドキュメントの引用です。

“ZgotmplZ” is a special value that indicates that unsafe content reached a CSS or URL context at runtime. The output of the example will be <img src=“#ZgotmplZ”> If the data comes from a trusted source, use content types to exempt it from filtering: URL(`javascript:…`)

これを解決するにはsafeHTMLAttrを使用します。

{{ $variable := "javascript:alert('Hello');" }}
<a {{ printf "href=%q" $variable | safeHTMLAttr }}>alert link</a>
<!-- 結果: <a href="javascript:alert('Hello');">alert link</a> -->

JavaScript / JSON

HTML内のJavaScriptやJSONに変数を出力する場合は同じ様に記述します。 JavaScriptやJSON用にエスケープしてくれます。

{{ $variable := "abc&def" }}
<script>
    const var = {{ $variable }}
</script>
/* 結果: 
<script>
    const value = "abc\u0026def"
</script>
*/

変数名に出力したい場合は、safeJSを使用します。

{{ $variable := "Abcdef" }}
<script>
    const value{{ $variable | safeJS }} = "hoge"
</script>
/*  結果: 
<script>
    const valueAbcdef = "hoge"
</script>
*/

まとめ

書く箇所によって、変数の出力のエスケープが変化します。 Hugoのドキュメントで明記されていないので注意が必要です。

iOS、Android、Web、APIサーバーなどのフロントエンド・バックエンドを開発するソフトウェアエンジニアです。 UI/UXが好きです。かっこいいUIやWebデザインを眺めるのが趣味です。 このブログはソフトウェア開発関係の内容を記事にしています。
web service:
GitHubQiitaTwitterはてなブログ
handle name:
nasust
real name:
hideki mori
job:
ソフトウェアエンジニア
develop:
target: ios, android, web page, single page application, api server, system service, cli tool, linux embedded device

lang: c/c++, go, swift, objective-c, java, kotlin, typescript, dart, javascript, ruby, python, php

tool: vscode, xcode, android studio, photoshop, vim, docker