/ #hugo

Hugo のテンプレート構成が変わっていた(0.146〜)

久しぶりに Hugo のテーマを書いたら

このサイトを Hugo 0.168 で作り直し、テーマも外部のものを使わず自分で書くことにしました。 昔の記憶のまま layouts/_default/ や layouts/partials/ を作ろうとしたのですが、 今の Hugo ではディレクトリ構成がすっきり変わっていました。 Hugo 0.146 で入った新しいテンプレートの仕組みのお話です。

何が変わったか

これまでの構成:

layouts/
├── _default/
│   ├── baseof.html
│   ├── list.html
│   └── single.html
├── partials/
│   └── head.html
├── shortcodes/
└── index.html

新しい構成:

layouts/
├── baseof.html
├── home.html
├── list.html
├── single.html
├── taxonomy.html
├── _partials/
│   └── head.html
├── _shortcodes/
└── _markup/
  • _default/ がなくなり、テンプレートは layouts/ 直下に置く
  • partials/ shortcodes/ は、頭に _ を付けて _partials/ _shortcodes/ にする
  • トップページは index.html ではなく home.html

_ が付いているのは「ページのテンプレートではない部品」という目印です。 _ の付かないディレクトリは、layouts/posts/single.html のようにセクション専用のテンプレートを置く場所として使われます。

テンプレートはページの種類で選ばれる

Hugo のページには home(トップ)、page(記事)、section(/posts/ など)、taxonomy(/tags/)、term(/tags/rails/)といった種類(Kind)があります。 新しい仕組みでは、まずこの種類と同じ名前のテンプレートを探し、なければ single.html や list.html で代用します。

このサイトではタグ別の一覧(term)専用のテンプレートを作らず、 /posts/ と同じ list.html に任せています。 違いを出したいところだけ、テンプレートの中で分けています:

<h1 class="site-title">{{ if eq .Kind "term" }}#{{ end }}{{ .Title }}</h1>

RSS も同じ考え方で、トップの RSS だけ変えたければ layouts/home.rss.xml を置けば済みます。

呼び出す側はそのまま

ディレクトリ名は _partials/ になりましたが、呼び出し方は今までと同じです:

{{ partial "head.html" . }}

また、古い構成のテーマもだいたいそのまま動くようになっているので、 既存のサイトを急いで書き換える必要はなさそうです。 新しく作るなら、迷わず新しい構成で書くのがよいと思います。

ついでに: 記事 URL をファイル名にする

旧サイトに合わせて記事の URL を /<ファイル名>/ にしたかったので、 hugo.yaml に次のように書きました:

permalinks:
  page:
    posts: /:contentbasename/

:contentbasename はファイル名(バンドルならディレクトリ名)になります。 この記事なら content/posts/hugo-new-template-system.md → /hugo-new-template-system/ です。

_default/ を探してしばらく迷いましたが、わかってしまえば今の構成の方がずっと見通しがよいです。 ぜひ。