ここではhugoのテーマの一つ一つがどう動いているのか?確認していきたいと思います。
前回までの記事は、
Wordpressからhugoへ | 橋本雄の日々の記録
まずはhugoを再度ゼロベースで作成しながら進めます
$ hugo new site theme-learning
$ hugo new theme my-theme
$ echo "theme = 'my-theme'" >> hugo.toml
$ hugo server -D
http://localhost:1313を見ると、
最低限のサイトが表示されるかと思います。
テンプレートの構造
├── archetypes
│ └── default.md
├── assets
│ ├── css
│ │ └── main.css
│ └── js
│ └── main.js
├── content (省略)
├── data
├── hugo.toml
├── i18n
├── layouts
│ ├── _partials
│ │ ├── footer.html
│ │ ├── head
│ │ │ ├── css.html
│ │ │ └── js.html
│ │ ├── head.html
│ │ ├── header.html
│ │ ├── menu.html
│ │ └── terms.html
│ ├── baseof.html 全てのページの基本となるもの
│ ├── home.html
│ ├── page.html
│ ├── section.html
│ ├── taxonomy.html
│ └── term.html
└── static
└── favicon.ico
構文の解説
Introduction to templating
layouts/baseof.html
全ての表示の起点となり一番の大枠です。
<!DOCTYPE html>
<html lang="{{ site.Language.LanguageCode }}" dir="{{ or site.Language.LanguageDirection `ltr` }}">
<head>
{{ partial "head.html" . }}
</head>
<body>
<header>
{{ partial "header.html" . }}
</header>
<main>
{{ block "main" . }}{{ end }}
</main>
<footer>
{{ partial "footer.html" . }}
</footer>
</body>
</html>
partialは、layouts/_partials/ の中を呼び出しています。 {{ block “main” . }}{{ end}} 部分が、メイン部分を呼び出しています。何を呼び出すかというと、hugoが設定しており、呼び出し元URLとして
- ホームURLから呼び出される場合: home.html
- Posts, Tagsなどリスト系:list.html
- 記事単独ページ: single.html
というルールとなっています。
layouts/home.html
{{ define "main" }}
{{ .Content }}
{{ range site.RegularPages }}
<section>
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ .Summary }}
</section>
{{ end }}
{{ end }}
こちらが、home.htmlで、元々のmainの定義を表しています。
{{.Content}} に、このページのコンテンツ、つまり content/_index.md の内容が表示される部分。
{{ range site.RegularPages }}....{{ end}}がコンテンツを繰り返し読み込む部分となります。
partial.footer.html
partialからは、hugo.tomlで設定した値を読み込むことが可能です
hugo.tomlで、以下のように記載します
[params]
author = "Hashimoto"
site_start = "2024"
partial/footer.htmlで以下のように記載すると
<p>
Copyright {{ .Site.Params.site_start }} - {{ now.Year }} {{ .Site.Params.author }}. All rights reserved.
</p>
以下のように表示されます

このように設定値を引き出すことが可能です。
テンプレートの優先順位
Template lookup order
実に柔軟な仕組みを提供しています。
content/
├── about.md
└── contact.md
ルートにあるコンテンツは、デフォルトでpageタイプとなります。このためテンプレートは、以下のsingle.htmlが適用されます
layouts/
└── page/
└── single.html
ところが、content/contact.mdのフロントマターに以下のように記載すると
layout: "contact"
以下のテンプレートが適用されます
layouts/
└── page/
└── contact.html <-- renders contact.md
└── single.html <-- renders about.md
コンテンツタイプをデフォルトのpageではなくて、意味のある名前をつけることで、規模の拡大に柔軟に対応できるようになります。
content/about.md
title: About
type: miscellaneous
content/contact.md
title: contact
layout: contact
type: miscellaneous
とすると、
layouts/
└── miscellaneous/
└── contact.html <-- renders contact.md
└── single.html <-- renders about.md
となります。
変数など
.(ドット)で始まる変数は、現在のコンテキストを表します。例えば、 page.htmlなどにある {{ .Title }}は、ページのmarkdownファイルのfrontmatterのtitleを表します。
繰り返し
{{range}}構文
{{ range slice "foo" "bar" }}
<p>{{ . }}</p>
{{ end }}
{{ with "baz" }}
<p>{{ . }}</p>
{{ end }}
とすると、
<p>foo</p>
<p>bar</p>
<p>baz</p>
範囲内でコンテキストを取得するには、ドットの前にドルマークを付けることで表示することができます。
{{ with "foo" }}
<p>{{ $.Title }} - {{ . }}</p>
{{ end }}