プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Hugo のテーマをアップデート

森ソフトの Webサイト は Hugo を使っています。この Hugo で使っているテーマをアップデートしたので、その際の作業をメモっておきます。

なお、作業は WSL (v1) 上の Ubuntu 18.04 で行っています。

テーマを更新

Web サイト自体は Netlify でホスティングしています。Netlify で使う場合はテーマ部分を git の submodule にしています。 なので、まずは、 submodule である Hugo のテーマ(現在は universal を利用)を最新に更新します。作業ディレクトリで確認すると、

mor@DESKTOP-H6IEJF9:/mnt/d/work/own_app/mywebsite/themes/hugo-universal-theme$ git tag
1.0.0
1.0.1
1.0.2
1.1.0
1.1.1
mor@DESKTOP-H6IEJF9:/mnt/d/work/own_app/mywebsite/themes/hugo-universal-theme$ 

とあるので、一番新しいリリースである 1.1.1 を利用します。

mor@DESKTOP-H6IEJF9:/mnt/d/work/own_app/mywebsite/themes/hugo-universal-theme$ git checkout tags/1.1.1
Previous HEAD position was f2f2c4f Https (#135)
HEAD is now at e45210f Avoid markify footer. (#251)
mor@DESKTOP-H6IEJF9:/mnt/d/work/own_app/mywebsite/themes/hugo-universal-theme$ 

これで、切替OKです。

新テーマに対応

Hugo で気に入っているところは、ディレクトリ構成がかっちりしてて、サイトのディレクトリ構成とテーマのディレクトリ構成が同じであるため、テーマ部分のあるファイルを変更したければ、対応するサイトのディレクトリ構成に同じ名前でファイルをコピーして変更することで、オーバーライドのようにカスタマイズできるところです。

このサイトも、いくつかのファイルについてカスタマイズしています。

なので、少し面倒ですが、新旧のファイルを比較して、新しいテーマの内容とカスタマイズの内容をマージする必要があります。

今回は次のようにしました。

  1. カスタマイズ済みのサイト側のファイルに、新しいテーマフォルダにある当該ファイルを上書きコピー
  2. カスタマイズ済みのサイト側のファイルはリポジトリに登録済みのため、テーマのバージョンアップに伴う差分を簡単に確認
  3. 差分がテーマのアップデート由来のものであれば、最新の記述を採用し、カスタマイズに由来するものであれば最新のスタイルに合わせて反映する

カスタマイズ用の変更前に、対応するファイルをテーマ側のディレクトリよりコピーした状態でリポジトリに登録しておけば、カスタマイズ部分を反映するのも簡単だったと思われます(まあ、いずれにしても一度は修正内容を確認しないといけませんが)。

作業が終わったら、 hugo server を実行してローカルで確認します。一応これで当初のサイトを復元することができました。

Formspree の新しいフォームスタイルへ対応

さて、これで問題ないかと思いきや、いろいろとテストしていると、この universal テーマのコンタクトフォームが正しく動作していないことがわかりました。つい先日までは動いていたんですけどね。

コンタクトフォームからの問い合わせ先のメールを見ると、 Formspree から 『PLEASE UPDATE YOUR LEGACY FORMS』というタイトルのメールが届いていました。 どういうことだろうかと思い、メール内のリンクを開いてみると、

Phasing out legacy forms (email URLs) – Formspree Help

とあります。

表示された記事を読んでみると、今までは、フォームのactionでメールアドレスを直接した形だったんですが、これをセキュリティ他の理由により Formspree の発行したエンドポイントを利用する形式に変更になったようです(直接的には今回のテーマのアップデートとは無関係だったようですね)。

なので、これに対応する必要があります。

対応方法

とはいえ、対応方法は難しいわけではなく、上記のリンク先の通り作業をすればOKです。一応手順を書いておきます。

まずは、 Formspree 側の作業です。

  1. Formspree に登録
  2. 確認用リンクが登録時のメールアドレスに送られてくるので、認証
  3. Formspree にログイン f:id:junichim:20201031155945p:plain
  4. 『+ New Project』ボタンを押してプロジェクトを作成(プロジェクトが1つもない場合)
  5. 『+New Form』ボタンを押す
  6. フォームを定義し、連絡先となるメールアドレスを指定する
  7. フォーム作成後、エンドポイントが表示されるので、それを控えておく f:id:junichim:20201031160334p:plain

今までは登録せずとも使えていたので、最初の登録に抵抗があるかもしれませんね。

次は、 Universal テーマ側の作業です。

config.toml を開いて、 email の部分をエンドポイントに変更します。なお、指定するエンドポイントは https://formspree.io/ を除いたものになります。

    email = "xxx/yyyyyyyyyyy"
    contact_form_ajax = false

これで、

hugo server

を実行して、コンタクトフォームを試すとちゃんとメールを受け取ることができました。

あとは、変更をリポジトリにアップして、本番環境へ反映して完了です。

一件落着。

(参考)

Hugo によるエラーの解消

実は、universal のテーマのアップデートの際に若干トラブルがあったので、下記に載せておきます。

最初、上記の作業の前に、テスト用サイトを作って、新しいバージョンのテーマでどうなるか確認してみました。すると、

mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test$ hugo new site sample
Congratulations! Your new Hugo site is created in /mnt/c/Users/mor/home/work/own_app/test/sample.
(略)
Visit https://gohugo.io/ for quickstart guide and full documentation.
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test$
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test$ cd sample/themes/
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes$ git clone https://github.com/devcows/hugo-universal-theme
(略)
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes$ cd hugo-universal-theme/exampleSite/
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/exampleSite$ hugo server -D

Building sites … ERROR 2020/10/30 21:56:26 Failed to add template "theme/partials/head.html" in path "/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/layouts/partials/head.html": template: theme/partials/head.html:10: unexpected "=" in operand
ERROR 2020/10/30 21:56:26 Failed to add template "theme/partials/recent_posts.html" in path "/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/layouts/partials/recent_posts.html": template: theme/partials/recent_posts.html:18: function "site" not defined
ERROR 2020/10/30 21:56:26 theme/partials/head.html : template: theme/partials/head.html:10: unexpected "=" in operand
ERROR 2020/10/30 21:56:26 theme/partials/recent_posts.html : template: theme/partials/recent_posts.html:18: function "site" not defined
ERROR 2020/10/30 21:56:26 Error while rendering "page" in "blog/": template: theme/_default/single.html:4:5: executing "theme/_default/single.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
ERROR 2020/10/30 21:56:26 Error while rendering "page" in "": template: theme/page/single.html:4:5: executing "theme/page/single.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
ERROR 2020/10/30 21:56:26 Error while rendering "section" in "": template: theme/_default/list.html:4:5: executing "theme/_default/list.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
ERROR 2020/10/30 21:56:26 Error while rendering "taxonomyTerm" in "": template: theme/_default/list.html:4:5: executing "theme/_default/list.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
ERROR 2020/10/30 21:56:26 Error while rendering "taxonomy" in "": template: theme/_default/list.html:4:5: executing "theme/_default/list.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
ERROR 2020/10/30 21:56:26 Error while rendering "home" in "": template: theme/index.html:4:5: executing "theme/index.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
ERROR 2020/10/30 21:56:26 Error while rendering "404" in "": template: theme/404.html:4:5: executing "theme/404.html" at <partial "head.html" ...>: error calling partial: template: "theme/partials/head.html" is an incomplete or empty template
Total in 326 ms
Error: Error building site: logged 4 error(s)
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/exampleSite$

こんな感じでエラーが大量にでてきました。

何が悪いのか全然わからないのですが、エラーメッセージでググると、全然別のプロジェクトで、Hugo が 0.40.x の時に似たようなエラーが出てるディスカッションがありました。

Severe: Failed to add template · Issue #703 · wowchemy/wowchemy-hugo-modules · GitHub

手元の hugo のバージョンを調べてみると、

mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/exampleSite$ hugo version
Hugo Static Site Generator v0.40.1 linux/amd64 BuildDate: 2018-04-25T17:16:11Z
mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/exampleSite$

どうもこれの可能性があるかもしれませんね。

今の Hugo は、確か、aptでインストールしたものを使っていたはずです。 apt だとバージョンが古いので、 snap を使えばもうちょっと新しいのが入るようですが、残念ながら WSL (v1) は snap が使えないようです。

なので、こちらの記事を参考に最新版を入れてみます。

まず、既存の Hugo をアンインストールします。

mor@DESKTOP-H6IEJF9:~$ sudo apt purge hugo
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
  gyp javascript-common libc-ares2 libhttp-parser2.7.1 libjs-async libjs-inherits libjs-jquery libjs-node-uuid libjs-underscore libpython-stdlib libpython2.7-minimal libpython2.7-stdlib libssl1.0-dev
  libuv1-dev nodejs-doc python python-minimal python-pkg-resources python2.7 python2.7-minimal
これを削除するには 'sudo apt autoremove' を利用してください。
以下のパッケージは「削除」されます:
  hugo*
アップグレード: 0 個、新規インストール: 0 個、削除: 1 個、保留: 305 個。
この操作後に 17.7 MB のディスク容量が解放されます。
続行しますか? [Y/n] y
(データベースを読み込んでいます ... 現在 42157 個のファイルとディレクトリがインストールされています。)
hugo (0.40.1-1) を削除しています ...
man-db (2.8.3-2ubuntu0.1) のトリガを処理しています ...
mor@DESKTOP-H6IEJF9:~$

次にリリースされている deb パッケージをダウンロードしてインストールします。

mor@DESKTOP-H6IEJF9:~$ wget https://github.com/gohugoio/hugo/releases/download/v0.77.0/hugo_0.77.0_Linux-64bit.deb
mor@DESKTOP-H6IEJF9:~$ sudo apt install ./hugo_0.77.0_Linux-64bit.deb
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
注意、'./hugo_0.77.0_Linux-64bit.deb' の代わりに 'hugo' を選択します
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
  gyp javascript-common libc-ares2 libhttp-parser2.7.1 libjs-async libjs-inherits libjs-jquery libjs-node-uuid libjs-underscore libpython-stdlib libpython2.7-minimal libpython2.7-stdlib libssl1.0-dev
  libuv1-dev nodejs-doc python python-minimal python-pkg-resources python2.7 python2.7-minimal
これを削除するには 'sudo apt autoremove' を利用してください。
以下のパッケージが新たにインストールされます:
  hugo
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 305 個。
14.0 MB 中 0 B のアーカイブを取得する必要があります。
この操作後に追加で 46.1 MB のディスク容量が消費されます。
取得:1 /home/mor/hugo_0.77.0_Linux-64bit.deb hugo amd64 0.77.0 [14.0 MB]
以前に未選択のパッケージ hugo を選択しています。
(データベースを読み込んでいます ... 現在 42128 個のファイルとディレクトリがインストールされています。)
.../hugo_0.77.0_Linux-64bit.deb を展開する準備をしています ...
hugo (0.77.0) を展開しています...
hugo (0.77.0) を設定しています ...
mor@DESKTOP-H6IEJF9:~$

無事にインストール出来たようです。

新しい Hugo のバージョンは 0.77.0 になりました。

mor@DESKTOP-H6IEJF9:~$ hugo version
Hugo Static Site Generator v0.77.0-EF290125 linux/amd64 BuildDate: 2020-10-30T10:14:31Z

再度試します。

mor@DESKTOP-H6IEJF9:/mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/exampleSite$ hugo server -D
Start building sites …

                   | EN
-------------------+------
  Pages            |  36
  Paginator pages  |   0
  Non-page files   |   0
  Static files     | 103
  Processed images |   0
  Aliases          |  14
  Sitemaps         |   1
  Cleaned          |   0

Built in 439 ms
Watching for changes in /mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/{archetypes,exampleSite,i18n,layouts,package.json,static}
Watching for config changes in /mnt/c/Users/mor/home/work/own_app/test/sample/themes/hugo-universal-theme/exampleSite/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

ちゃんと動きましたね。

疑問点

上記のように、 Hugo のバージョンを新しくしたことで解決したのはいいのですが、ただ、 universal もアップデート前のものを使っていた時は、 0.40.1 の Hugo でも問題なく動作していました。テーマとの兼ね合いもあるのかもしれませんね。

ま、何かのご参考までに。