Hugo のテーマを git submodule から Hugo Modules に移行したときの Harbor Theme の対応

submodule で管理されてたテーマを Hugo Modules に変えたら壊れたので AI に直させたログをそのまままとめたやつです。

はじめに

Hugo サイトで Harbor Theme を使用している際に、テーマを git submodule から Hugo Modules に移行したところ、新しいバージョンの Hugo (v0.147.9) でいくつかの互換性エラーが発生しました。この記事では、それらのエラーの原因と解決方法をまとめます。

発生したエラー

hugo server -D を実行すると、以下のようなエラーが発生しました:

ERROR render of "..." failed: ... at <.Site.IsServer>: can't evaluate field IsServer in type page.Site
ERROR ... at <.Site.DisqusShortname>: can't evaluate field DisqusShortname in type page.Site
ERROR ... at <.Site.GoogleAnalytics>: can't evaluate field GoogleAnalytics in type page.Site
ERROR ... at <resources.Concat>: expected slice of Resource objects, received []interface {} instead
ERROR ... at <$theme.RelPermalink>: nil pointer evaluating resource.Resource.RelPermalink
ERROR deprecated: .Site.Author was deprecated in Hugo v0.124.0 and subsequently removed
ERROR deprecated: .Site.LastChange was deprecated in Hugo v0.123.0 and subsequently removed

原因分析

これらのエラーの原因は、Harbor Theme v1.0.0 が古いバージョンで、Hugo の新しいバージョンで廃止されたAPIを使用していることでした。

主な問題点は以下の通りです。

  1. 廃止されたサイト変数の使用: .Site.IsServer, .Site.DisqusShortname, .Site.GoogleAnalytics など
  2. resources.Concat の型エラー: 新しいバージョンでの slice の扱い方の変更
  3. 存在しないリソースファイルへの参照: nil ポインタエラーの原因
  4. 設定ファイルの構造変更: Author 設定の移動

解決手順

1. テンプレートファイルのローカルオーバーライド

Harbor Theme の問題のあるテンプレートファイルを layouts/partials/ ディレクトリにコピーして、ローカルでオーバーライドします。

2. analytics.html の修正

修正前:

{{ if or ( .Site.Params.enableGoogleAnalytics ) ( not .Site.IsServer ) }}
  {{ with .Site.GoogleAnalytics }}

修正後:

{{ if or ( .Site.Params.enableGoogleAnalytics ) ( not hugo.IsServer ) }}
  {{ with site.Config.Services.GoogleAnalytics.ID }}

3. disqus.html の修正

修正前:

{{ with .Site.DisqusShortname }}

修正後:

{{ with site.Config.Services.Disqus.Shortname }}

4. head.html の修正

resources.Concat の型エラー修正

修正前:

{{ $styles := (slice $main $syntax) | resources.Concat "css/styles.css" | minify }}

修正後:

{{ $main := resources.Get "css/main.css" }}
{{ $syntax := resources.Get "css/syntax.css" }}
{{ if and $main $syntax }}
  {{ $styles := slice $main $syntax | resources.Concat "css/styles.css" | minify }}
{{ end }}

リソースファイルの存在チェック追加

修正前:

{{ $theme := resources.Get "js/theme.js" }}
<script src="{{ $theme.RelPermalink }}"></script>

修正後:

{{ $theme := resources.Get "js/theme.js" }}
{{ if $theme }}
<script src="{{ $theme.RelPermalink }}"></script>
{{ end }}

minify の型エラー修正

修正前:

{{ $dark := resources.Get "css/dark.css" | minify }}

修正後:

{{ $dark := resources.Get "css/dark.css" }}
{{ if $dark }}
  {{ $dark = $dark | minify }}
{{ end }}

5. config.toml の修正

Author 設定の移動

修正前:

[Author]
    name = "しの"

修正後:

[params.author]
    name = "しの"

6. rss.xml の修正

修正前:

<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>

修正後:

<managingEditor>{{.}}{{ with $.Site.Params.author.name }} ({{.}}){{end}}</managingEditor>

変更されたAPIの対応表

旧API新API
.Site.IsServerhugo.IsServer
.Site.DisqusShortnamesite.Config.Services.Disqus.Shortname
.Site.GoogleAnalyticssite.Config.Services.GoogleAnalytics.ID
.Site.Author.name.Site.Params.author.name
.Site.LastChange.Site.Lastmod
{{&lt; tweet &gt;}}{{&lt; x &gt;}}
{{&lt; twitter &gt;}}{{&lt; x &gt;}}
{{&lt; twitter_simple &gt;}}{{&lt; x &gt;}}

結果

これらの修正により、主要なエラーはすべて解決され、Hugo サイトが正常にビルドされるようになりました。

解決されたエラーは以下の通りです。

  • .Site.IsServer のエラー
  • .Site.DisqusShortname のエラー
  • .Site.GoogleAnalytics のエラー
  • resources.Concat の型エラー
  • リソースファイルの nil ポインタエラー
  • .Site.Author の廃止エラー

残った警告は以下の通りです。

  • .Site.LastChange の廃止警告(動作には影響なし)
  • Twitter ショートコードの廃止警告(動作には影響なし)

残りの問題の解決

7. footer.html の修正

最後の .Site.LastChange エラーは footer.html に存在していました。

修正前:

<a href="{{ "" | absLangURL }}about">{{ .Site.Author.name }}</a>
&nbsp;&copy;
{{ .Site.LastChange.Format "2006" }}

修正後:

<a href="{{ "" | absLangURL }}about">{{ .Site.Params.author.name }}</a>
&nbsp;&copy;
{{ .Site.Lastmod.Format "2006" }}

8. Twitter ショートコードの置換

Hugo v0.142.0 で twittertweettwitter_simple ショートコードが廃止され、x ショートコードに変更されました。

一括置換コマンド:

find content -name "*.md" -type f -exec sed -i 's/\{\{< tweet /\{\{< x /g' {} \;

修正前:

{{&lt; tweet user="PureIllusionist" id="1559156113559343104" &gt;}}

修正後:

{{&lt; x user="PureIllusionist" id="1559156113559343104" &gt;}}

最終結果

すべてのエラーと警告が解決され、Hugo サイトがエラーフリーで動作するようになりました。

解決されたエラーは以下の通りです。

  • .Site.IsServer のエラー
  • .Site.DisqusShortname のエラー
  • .Site.GoogleAnalytics のエラー
  • resources.Concat の型エラー
  • リソースファイルの nil ポインタエラー
  • .Site.Author の廃止エラー
  • .Site.LastChange の廃止エラー
  • Twitter ショートコードの廃止警告

テーマ表示問題の発見と解決

エラーを全て修正した後、実際にサイトが正しく表示されているかを確認するため、Playwright を使って表示チェックを行いました。

問題の発見

ブラウザでサイトを確認すると、Harbor Theme のスタイルが正しく適用されていないことが判明しました。ヘッダーナビゲーション、ロゴ、記事レイアウトなどのテーマ固有のデザインが表示されていませんでした。

原因調査

ネットワークリクエストを調査した結果、Harbor テーマのメインCSSファイル(css/main.cssなど)が読み込まれていないことが分かりました。

問題の原因は、head.htmlresources.Get を使ってassetsディレクトリからCSSファイルを読み込もうとしていたことでした:

{{ $main := resources.Get "css/main.css" }}
{{ $syntax := resources.Get "css/syntax.css" }}
{{ if and $main $syntax }}
  {{ $styles := slice $main $syntax | resources.Concat "css/styles.css" | minify }}
  <link rel="stylesheet" href="{{ $styles.RelPermalink }}">
{{ end }}

しかし、Harbor Theme では CSS ファイルが static/css/ ディレクトリに配置されており、resources.Get では見つけることができませんでした。

解決方法

元の Harbor Theme の head.html を確認すると、CSS や JavaScript ファイルは直接参照する方式で読み込まれていました。そこで、head.html を元のテーマの方式に戻すことにしました。

修正後の head.html(CSS部分):

<link rel="stylesheet" href="{{ .Site.BaseURL }}css/main.css">
<link rel="stylesheet" href="{{ .Site.BaseURL }}css/syntax.css">
{{ if .Site.Params.enableDarkMode }}
<link rel="stylesheet" href="{{ .Site.BaseURL }}css/dark.css">
{{ end }}

修正後の head.html(JavaScript部分):

<script src="{{ .Site.BaseURL }}js/theme.js"></script>
{{ if eq .Type "search" }}
<script src="{{ .Site.BaseURL }}js/search.js"></script>
{{ end }}

結果確認

修正後、ブラウザでサイトを再確認すると、Harbor Theme が正しく表示されることが確認できました。

確認できた表示要素は以下の通りです。

  • ヘッダーナビゲーション(About, Likes, Tags, Search)
  • ロゴ画像
  • 記事一覧のレイアウト
  • 日付表示
  • Read More リンク
  • 全体的なデザインとレイアウト

完全解決後の最終結果

全てのエラーが解決され、テーマも正しく表示されるようになりました。

解決されたエラーは以下の通りです。

  • .Site.IsServer のエラー
  • .Site.DisqusShortname のエラー
  • .Site.GoogleAnalytics のエラー
  • resources.Concat の型エラー
  • リソースファイルの nil ポインタエラー
  • .Site.Author の廃止エラー
  • .Site.LastChange の廃止エラー
  • Twitter ショートコードの廃止警告
  • テーマ表示問題

最終的な修正ファイル一覧は以下の通りです。

  • layouts/partials/analytics.html
  • layouts/partials/disqus.html
  • layouts/partials/head.html
  • layouts/partials/footer.html
  • layouts/rss.xml
  • config.toml
  • 全ての .md ファイル(Twitter ショートコード置換)

まとめ

Hugo のバージョンアップに伴い、古いテーマでは互換性の問題が発生する可能性があります。特に注意が必要な点は以下の通りです。

  1. 廃止されたAPIの確認: Hugo のリリースノートで廃止されたAPIをチェック
  2. テンプレートのローカルオーバーライド: 問題のあるテンプレートファイルをローカルで修正
  3. 設定ファイルの更新: 新しい設定構造に合わせて調整
  4. リソースファイルの存在チェック: nil ポインタエラーを防ぐための条件分岐

テーマの更新が追いついていない場合は、このような個別対応が必要になりますが、適切に修正すれば新しいバージョンの Hugo でも問題なく動作させることができます。

今回の経験から、Hugo Modules への移行は便利ですが、古いテーマを使用している場合は互換性の問題に注意が必要であることがわかりました。しかし、エラーメッセージは明確で、修正方法も比較的シンプルなので、一つずつ対応していけば確実に解決できます。

参考資料