💎

静的サイトジェネレーターHugoの導入

2021/10/17に公開

Hugoはオープンソースの静的サイトジェネレーターの一つです。
脅威的なスピードに惚れて使ってます。

軽く触ってみた比較

15年ぶりのサイト更新です。以前はPHPで独自テンプレートエンジンを書いて構成を統一していました。
中には動的な機能も用意していましたが、なくても困らない機能だったので今回は静的サイトに変更しています。
その際、OSSを使ってみようと探した結果見つけたのがHugoでした。他にはGatsbyがReactベースで面白そうだなと思いました。

HugoとGatsbyのチュートリアルをやってみて私にはHugoの方が合ってました。
Gatsbyの方がサイト生成時にGraphQLでゴニョゴニョできるカスタマイズ性は高そうですし、
生成されたサイトはReactが導入されておりページ遷移が早いようです(部分的な仮想DOM操作)。
ただその分とっかかりが大変そうだったり、Javascript製でツールの速度が気になってしまいました。
ツール速度に関してはM1 Mac miniでdockerコンテナで構築している関係もあるかもしれません。
またGatsbyをテストサーバーモードで起動した時、M1 MacのSafariだとホームページしか表示できず個別ページが表示できなかったりしました。
表示できない問題はChromeを使えば問題なかったし、テストサーバーモードで起動後はデータ保存時の即反映は遅くなく十分早かったです。

その点HugoではM1 Mac上のdockerコンテナでも問題なく動き、スピードも申し分ありません。
私は凝ったことはせず単純にMarkdownを静的サイトに変換したかっただけなので、機能的にHugoで満たしていたため採用しました。
ただReactはチュートリアルしかやってませんが、Javascriptで人気No1フレームワーク(ライブラリ)なだけあり良さげでした。
JSXという表記方法も分かりやすくてその点は、HugoのGoテンプレートより好きです。

Hugo導入

Hugo Quick Start で最低限の使い方を学べます。
英語ですがコマンドがあるのでなんとなく分かります。

私はテーマとしてPaperModを使っています。
LEARNというテーマも良さげ。
個人的には2カラム構成の方が横長ウィンドウにあっていると思うのですが、シンプルでダークテーマ切り替えもできるPaperModを選択しました。
出来れば、サイトマップや広告をサイドに表示して、目次をスクロールに追随させたいです。
テーマを自作すればできるのですが、Hugoの使ってるテンプレート表記が見づらいしCSSの勉強し直し(Pre/Post-processorとか知らないし)もありほぼそのまま使用しています。
ただし今のサイトは指定された広告挿入が必要なので、少しだけカスタムしてます。

設定のTips

Hugo公式やテーマの公式をみながら設定していきました。
その中のいくつか忘れそうなものをピックアップしてみます。

コンバート出力対象を指定

# HTML => 普通のサイト
# RSS => RSS用のXMLファイル
# JSON => 検索用のjsonファイル
[outputs]
home = [ "HTML", "RSS", "JSON" ]

検索用のjsonファイルはテーマが対応していないとダメです。
PaperModテーマの場合 content/search.md を作りFont Matterに layout: "search" を指定することで、検索ページ(/search/)が作られます。

日付の表記

[params]
DateFormat = "2006-01-02"

Goの仕様なのか日付のフォーマット指定が独特で、この数字 2006,01,02 に意味があるらしいです。2006年ってなんや。

コンテンツ処理対象の指定

[params]
mainSections = [ "book", "post", "tips" ]

params.mainSections に指定したセクション名(content下の第一階層)がコンテンツ処理対象になります。
ホームページに表示する記事一覧や検索対象など。最初のうちはサイト構成が固まってないので時々変更が必要なので忘れないようにしよう。

RSSコンテンツ

[params]
ShowFullTextinRSS = false
[services.rss]
limit = 15

記事全文がRSSに含まれないように、ShowFullTextinRSSを指定しています。
含まれるのはDescriptionだけになるので、記事個別ページのFront Matterに description: の指定をしていきます。

メニュー表示

[[menu.main]]
identifier = "tags"
name = "tags"
url = "/tags/"
weight = 10

[[menu.main]]
identifier = "search"
name = "search"
url = "/search/"
weight = 30

[[menu.main]] 配列でメニューに表示する項目を指定します。

独自変数の追加

[params]
AdSense="..."

このように追加するとテンプレート内で { if site.Params.AdSense }} のように参照できます。
個別ページだと {{ if (.Param "AdSense") }} のように関数で呼び出すことでMarkdownのFront Matter内で AdSense: ... と書けば優先されます。
(この辺り挙動をきちんと把握してないので、ホームページだと意図した変数に参照できてない問題に遭遇していますが、運用でカバー。。。)

記事のTips

MarkdownのFront Matterという、ページ先頭にプロパティを指定する機能があります。
--- で区切れば YAML+++ で区切れば TOML{...} 表記で JSON#+ 表記で ORG の各書式に対応していいます。
個人的には多数の設定があればTOML、入子がなければYAMLが好みです。
TOMLのように入れ子をインデントしなくていいのは入れ子が多い場合見やすいし、同セクションが複数箇所でも良いのはグループ分けしやすいので好きです。
またYAMLのように文字列を"で囲まなくても良いのも書きやすいし、=より:の方が定義感があり良いです。

---
title: Introduction
date: 2021-10-17T13:02:25Z
tags: [tips, hugo]
draft: true
description: |-
  [Hugo](https://gohugo.io)はオープンソースの静的サイトジェネレーターの一つです。
  脅威的なスピードに惚れて使ってます。
---

description はいくつかの場所で参照するので指定しています。
複数行を書きたいので、ヒアドキュメント構文を使って記載しています。(YAMLではインデントが必要)

テンプレートのTips

このサイトはPaperModを基本としていますが、一部だけテンプレートを直接書き換えています。
きちんと対応するならば、/theme/PaperMod/layouts/*.html のファイルに変更せず、 /layouts/*.html で上書きするのが正攻法です。
その際 {{ partial "hoge.html" }} とあれば、/layouts/partial/hoge.html だけ用意すれば良いのでうまく分離ができます。

今回、私は手抜きをして /theme/PaperMod/layouts/*.html 側も直接変更してしまいました。
将来的には自分でテーマ(かそもそも静的サイトジェネレーター)を作りたいです。

minify出力

Hugoの引数に --minify を指定すると、minify出力できます。
効果がどのくらいあるかは見てませんが、小さいに越したことはないということで使ってます。
configファイルにも記載できるようですが、詳しいドキュメントを見つけられず(英語が読めず?)、
正しく動いてなさそうという記事もあったのでコマンドラインで指定します。
忘れてしまいそうなので、できればconfig.tomlに書きたい。

出力先は消されない

Hugoで生成するときに出力先が存在すれば、ノータッチで成果物が作られます。
そのため、期限切れとかリネームしたページが残ったままになるので必要なら対策をしましょう。

Discussion