Hugo テンプレートをカスタマイズする前に知っておきたいハイフン"-"の意味

静的サイトジェネレーター Hugo のテンプレートをカスタマイズし始めると様々な変数を目にすることになります。 Hugo Themes にあるような様々なテンプレートを参考するケースもあるかと思いますが、すると、作者によってタグの囲み方に違いがあることに気が付きました。 例えば、頻繁に使う構文のひとつである with の代表的な記載は以下の通り。

{{ with .Params.title }}
    <h4>{{ . }}</h4>
{{ end }}

ですが、作者によって、{{- with -}} というように、前後にハイフンがあったり無かったりします。

最初は、正直どちらでも意図した通りに動くし気にする必要はないと思っていたのですが、やはりモヤモヤしてきたので調べた結果をメモします。

Hugoテンプレート構文内のハイフンの意味

こちらで質問、回答が記載されています。
Use of dash in between curly brackets? {{- code -}} - support - Hugo Discussion

結果、空白 (white-space) を除去してくれる とのこと。そして、これはちゃんと公式ドキュメントに記載されているよ、ということでした。

Introduction to Hugo Templating | Hugo

- について疑問をもって、これを主目的として検索しようにもうまく検索で絞り込めないし、ちょっと見つけづらいですね・・・(よく読みましょう、ということだが)。

ハイフン有無の動作検証

前述の公式(Introduction to Hugo Templating)に記載されているサンプルで十分理解できますが、以下の通り動作します。

検証用ベースHTML。前後においている--は、スペース除去による距離感を測るための記述として読んでください。

--
<!-- begin -->
{{ with .Site.BaseURL }}
<div>
  <h1>
    {{ . }}
  </h1>
<div>
{{ end }}
<!-- end -->
--

実行結果は以下の通り、HTMLタグにおけるコメント記述行とHugoテンプレートタグの行それぞれが消えるものの、行としては残り続けています。

--


<div>
  <h1>
    http://localhost:1313/
  </h1>
<div>


--

{{ with .Site.BaseURL -}} として片方に1個追加するケース

--
<!-- begin -->
{{ with .Site.BaseURL -}}
<div>
  <h1>
    {{ . }}
  </h1>
<div>
{{ end }}
<!-- end -->
--
--

<div>
  <h1>
    http://localhost:1313/
  </h1>
<div>


--

上部 --<div> の距離が詰まっていることがわかります。

{{- with .Site.BaseURL -}} として両サイドに追加するケース

--
<!-- begin -->
{{- with .Site.BaseURL -}}
<div>
  <h1>
    {{ . }}
  </h1>
<div>
{{ end }}
<!-- end -->
--
--
<div>
  <h1>
    http://localhost:1313/
  </h1>
<div>


--

--<div>の距離が完全になくなりました。左右のハイフン-1個ずつ1行、計2行分が動いているのがわかります。

裏付け検証

ここまでの確認で挙動把握としては十分ですが、そのまま続いて公式ドキュメントの動作も確認します。

h1 タグ内のURL表示の右部分にハイフンを付与します。

--
<!-- begin -->
{{- with .Site.BaseURL -}}
<div>
  <h1>
    {{ . -}}
  </h1>
<div>
{{ end }}
<!-- end -->
--

--
<div>
  <h1>
    http://localhost:1313/</h1>
<div>


--

URLの直後の</h1>タグが移動しています。
そして最終的に、全部ハイフンを付与すると・・・

--
<!-- begin -->
{{- with .Site.BaseURL -}}
<div>
  <h1>
    {{- . -}}
  </h1>
<div>
{{- end -}}
<!-- end -->
--
--
<div>
  <h1>http://localhost:1313/</h1>
<div>
--

スッキリしました。

意識的にハイフンを使うべきシーン

意識的に使うべきシーンとしては、JSONなどの構造を表現する必要がある時、改行されては困るシーンくらいでしょうか。

たとえば、keywords というキーに対して記事のカテゴリ名・タグ名・キーワードを詰め込みたい場合を例にします。

{{/* 変数の定義 */}}
{{ $tags := .Params.tags | default (slice) }}
{{ $cats := .Params.categories | default (slice) }}

{{/* カンマ区切りで詰め込む処理 */}}
"keywords" : [
  {{ range $i, $e := $cats }}
    {{ if $i }}, {{ end }}
    {{ $e }}
  {{ end }},
  {{ range $i, $e := $tags }}
    {{ if $i }}, {{ end }}
    {{ $e }}
  {{ end }}
],

入れ子の見通しをよくするために改行を入れてしまうとJSON出力が期待しない表示になってしまう。

"keywords" : [


    "カテゴリ名"
  ,


    "タグ名"

],

そのため、以下の通りに修正。

"keywords" : [
  {{- range $i, $e := $cats -}}
    {{- if $i }}, {{ end -}}
    {{- $e -}}
  {{- end -}},
  {{- range $i, $e := $tags -}}
    {{- if $i }}, {{ end -}}
    {{- $e -}}
  {{- end -}}
],
"keywords" : ["カテゴリ名","タグ名"],

いい感じに空白・改行が除去され、期待通りの表示になりました。

ハイフン有無の動作仕様まとめ

まとめると以下の特徴があります。

  • テンプレート変数にハイフン - を設定すると、設定した部分の空白を除去してくれる
  • ハイフン - は左右どちらか1個ずつでも設定することができる

個人的な結論ですが、原則(前述例外あり) は利用する必要はないと思いました。

何故かと言うと、Hugoではデプロイ時に Minify (スペースや改行をとことん取り除いてファイルサイズを小さくし、少しでも配信を効率的にするための圧縮。hugo --mifiy で実行できる。)してしまうので、HTML構造をしっかりチェックしたいシーンというとThemeカスタマイズ中などの限られたシーンです。更には、カスタマイズをする際には Google Developer Tool などの Inspector を利用することが大半かと思いますので、ブラウザのソース表示機能における美しさはさほど重要視されないでしょう。

というわけで、テーマファイル郡を操作する際にどちらで編集するのが好みであるか という点に尽きると考えます。 それはハイフンにより空白除去が目的というよりも、テンプレート構文として「どちらがそれっぽいか」という、テーマ作成者・編集者の嗜好という観点です。

「前後にハイフンを入れたほうがテンプレート構文っぽい!({{- with .Site.BaseURL -}})」 という感性もよいですし、「ハイフン入れるとなんとなく違和感があるし、タイプ数も増えるし、スッキリした方がいい!({{ with .Site.BaseURL }})」という感性もまたよいでしょう。 ただ、同じテーマ内に記載方法が乱立しているとポリシー面(コーディング規約とかの観点)が曖昧になってしまうので、テーマ内でそうだと決めたらそれを貫いたほうがよいものと思います。

他には、”全員が Minify するわけではない” という前提のもと、よりベターとなる選択としてハイフンを利用する、という価値観もあるかもしれません。
なお、hugo --minify については、静的サイトジェネレーター比較記事 でも多少触れました。ご参考まで。