Hugoのテーマ作成のやり方

2018-08-25
2018-08-25

Hugo でテーマを自作

Hugo を使って、静的ホームページを作成する。Hugo ではいくつか無料で利用可能なテーマがあるが、せっかくなので自分用のテーマを作成してみます。

ここからはすでに Hugo がインストールされている前提で話しますので、インストールはお願いします!

※ (2020/1/19 追記) インストール方法記載しました ↓
Hugo を使ったブログ運営方法の紹介

新規テーマの作成

まずは下記コマンドで新しいテーマを作成します。

hugo new theme [テーマ名]

実行後のルート以下のファイル構造は以下のようになります。

├── archetypes
   └── default.md
├── config.toml
├── content
   └── post
       └──test.md
├── data
├── layouts
├── resources
├── static
└── themes
    └── myTheme
        ├── LICENSE
        ├── archetypes
           └── default.md
        ├── layouts
           ├── 404.html
           ├── _default
              ├── baseof.html
              ├── list.html
              └── single.html
           ├── index.html
           └── partials
               ├── footer.html
               ├── head.html
               └── header.html
        ├── static
           ├── css
           └── js
        └── theme.toml

themes 配下にテーマ名 myTheam というのが生成されています。これが今回新しく作ったテーマです。

hugo にはいくつかの template が用意されており、各 templatate によって読み込まれる順番があります。 以下に base template の例を示します。

  1. /layouts/section/-baseof.html
  2. /themes/layouts/section/-baseof.html
  3. /layouts/baseof.html
  4. /themes/layouts/baseof.html
  5. /layouts/section/baseof.html
  6. /themes/layouts/section/baseof.html
  7. /layouts/_default/baseof.html
  8. /themes/layouts/_default/baseof.html
  9. /layouts/_default/baseof.html
  10. /themes/layouts/_default/baseof.html

引用: Base Template

このように読み込みに優先順位があるので、ダウンロードした theme を用いる場合などに、優先度の高いファイルに新しく記述することで上書きができます。

新しく theme を作る場合は、一番優先度の低い/themes/<THEME>/layouts/_default/baseof.htmlのファイルの編集をします。ただし、どうやらbaseof.htmlより/themes/<THEME>/layouts/index.htmlが優先されるようです。 簡単にするためにindex.htmlを削除してもいいらしいです。

ページの作成

ページのレイアウトは以下の順番で行います。

  1. index.html
  2. baseof.html
  3. head.html
  4. list.html
  5. single.html
  6. header.html
  7. sidebar.htnl

layout配下のindex.htmlには以下のような記述をしました。

{{ define "title" }} {{ .Title }} &ndash; {{ .Site.Title }} {{ end }} {{ define "main" }} This is
test

<main>
  <!-- root直下の/content/post/内の記事を10個まで表示 -->
  <!-- rangeはループ -->
  {{ range first 10 .Data.Pages }}
  <div>
    <!-- .Titleで記事のタイトルを表示 -->
    <a href="#">{{ .Title }}</a>
    <!-- .Contentは記事の内容を全て表示 -->
    {{.Content}}
  </div>
  {{ end }}
</main>
{{ end }}

ただ、これだけでは何も表示されないです。 {{define "name"}}{{end}}とすることで{{block "name" .}}{{end}}で他のファイルから呼び出すことができます。これを用いて次はbaseof.htmlを記述していきます。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>{{ block "title" . }} {{ .Site.Title }} {{ end }}</title>
    <link rel="stylesheet" href="{{"/css/custom.css"|relURL }}">
  </head>
  <body>
    {{ block "main" . }}
    <!-- define "main"の内容が表示される -->
    {{ end }}
  </body>
</html>

これで下記のコマンドをルート直下で実行します。

hugo server --theme=myTheme --buildDrafts=true --watch -v

ブラウザでhttp://localhost:1313にアクセスすると content/post 以下に配置された.md ファイルが表示されます。

html の部品化

Hugo では、html を部品化することができます。myTheme/patials/配下のhead.htmlbaseof.htmlの一部を以下のようにコピペします。

<head>
  <meta charset="utf-8" />
  <title>{{ block "title" . }} {{ .Site.Title }} {{ end }}</title>
  <link rel="stylesheet" href="{{"/css/custom.css"|relURL }}">
</head>

次にbaseof.htmlを以下のように編集します。

<!DOCTYPE html>
<html lang="ja">
  {{partial "head" .}}
  <body>
    {{ block "main" . }}
    <!-- define "main"の内容が表示される -->
    {{ end }}
  </body>
</html>

{{partial "○○.html"}}で patials 配下の html を挿入することができます。

このようにbaseof.htmlと部品化された html を用いることでコード可読性やカスタマイズ性をあげることができます。

ここまでの状態をブラウザで確認すると記事がいくつか縦にずらずらと表示されているはずです。このままだと読みづらいのでタイトルと少量の内容だけを表示して記事をリスト化してみます。

list.htmlに以下のように記述します。

<div>
  <!-- 記事タイトルをリンクにする -->
  <a href="{{ .Permalink }}">{{ .Title}}</a>
  <div>{{ .Date.Format "2006-01-15" }}</div>
  <p>{{ .Summary}}</p>
</div>

内容としては記事のタイトルと書かれた日時と記事のうち定められた語数だけを表示するといったものです。

ちなみにここでハマったこととして日時の指定を日本っぽい並び順にしたい場合は、2006-01-15と必ず書かなければならないようです。2018-03-19とか異なる年月日では正しく表示されなかったです(バグなのかはわからない)。

これだけでは変更が反映されないの、今書いた内容を読み込むようにindex.htmlを編集します。

{{ define "title" }} {{ .Title }} &ndash; {{ .Site.Title }} {{ end }} {{ define "main" }}
<main>
  <!-- root直下の/content/post/内の記事を10個まで表示 -->
  <!-- rangeはループ -->
  {{ range first 10 .Data.Pages }}
  <div>
    <!-- list.htmlを読み込む -->
    {{ .Render "list"}}
  </div>
  {{ end }}
</main>
{{ end }}

これでリスト化された記事が表示されると思います。

続いて各記事の詳細画面の設定を行います。Hugo は記事の詳細には\_default 配下の single.html が優先で適用されます。先ほどの list.html{{ .Permalink }}は各記事へのパスを示します。 single.html に以下のように記述します。

{{ define "title" }} {{ .Title }} &ndash; {{ .Site.Title }} {{ end }} {{ define "main" }}
<main>
  <article>{{ .Content }}</article>
</main>
{{ end }}

これでindex.html{{define "main"}}が上書きされます。

まとめ

この記事では Hugo のテーマを自作する場合の基本的な流れについて説明しました。 記事中のコードで使用していた Go の html/template の記述方法や Hugo でデフォルトで使用できる変数や関数については別途記事にすつもりです。