Hugoテーマの学習

2 Mins read

ここでは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

An introduction to Hugo's templating syntax.

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

Hugo uses the rules below to select a template for a given page, starting from the most specific.

実に柔軟な仕組みを提供しています。

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 }}