ブログを改良しました。

2023年の最初の記事です。

このブログは静的サイトジェネレータ「Hugo」で構築しています。
実は昨年にブログを開設して以降、テンプレートや設定ファイル等、ほとんど触っていませんでした。
1から作り込んだのは、プログラム表示用のシンタックスハイライト部分くらいでした。
今回、色々と手を加えてみたので備忘録として残します。

これからHugoを触る方にとって、何かのヒントになれば幸いです。
大まかに、以下のことをやっています。

  • 本番環境のHugoのバージョンをアップグレードした
  • RSSの出力内容を刷新した
  • 記事管理の構造をページバンドル式にした
  • tcardgenを使ってOGP画像を生成出来るようにした
  • リソースをassetsに配置してHugoのImage Processingを有効活用した
目次 - CLICKで開閉します -

本番環境のHugoのバージョンをアップグレードした

ここで解説する方法は、Netlify上でビルドを行う場合の例になります。

以下はアップグレード後のnetlify.tomlのDiffです。
変更箇所はここのみ。NetlifyにデプロイするとHugo 0.109.0でビルドしてくれます。私の環境では0.81が使われていたので、普段Macで動作させているバージョンに合わせました。

+[context.production.environment]
+HUGO_VERSION = "0.109.0"
+HUGO_ENV = "production"
本番環境のバージョンが勝手に上がってしまうことは無いと思いますが、想定外の動作異常を避けるためにもバージョンは指定しておいた方が良さそうです。

RSSの出力内容を刷新した

仕上がりは以下のようなイメージです。
記事一枚目の画像の下に冒頭文、そして最後に 【続きを読む】を表示させています。

スクリーンショット開閉
test steron
RSSリスト表示時
冒頭文
続きを読む部分

今までRSSの出力をHugoのデフォルト機能に任せていましたが、色々と気に食わなかったので自分でテンプレートを用意しました(笑) 。 以下はRSSテンプレートの説明と、GitHub上の標準テンプレートです。
これをベースにlayouts/_default/rss.xmlを作成しました。

冒頭記事はcontent:encodedタグへ、 画像はmedia:contentタグへ設定することで、RSSリーダが良い具合に読み取ってくれるようです。 デフォルトではdescriptionタグに冒頭記事が設定されますが、RSSの仕様として長い文章は指定しないことが推奨されるようです。このため、明示的にコンテンツを表示するためのcontent:encodedを使っています。

記事管理の構造をページバンドル(PageBundle)にした

大きく2点。サイト構成を、2種類あるPageBundle方式のひとつ、LeafBundle方式にしました。
そして導入テーマの都合上、staticcontent/imagesに置いていた画像ファイルをassetsに移動しました。
その過程でショートコードやテンプレートにも手を加えました。
結果としてファイル構成がシンプルになり、HugoのResource機能も使えるようになりました。

LeafBundleassetsについては、以下公式が参考になります。

最終的にどうしたか

共通のリソースはassets配下に格納しました。

assets/
├── js/
├── css/
├── font/
└── images/

記事はcontent/posts配下に記事ごとのディレクトリを作成して格納しました。

content/
├── _index.md
├── images/
│   └── index.md
├── posts/
│   └── site_updating_202301/ # 投稿記事単位で、content/posts 配下にディレクトリを作成
│       ├── index.md
│       └── index.png

以前の構成

元々は、記事として表示しないcontent/imagesセクションに、全ての記事画像を置いていました。
どの画像がどの記事と関連があるのか非常にわかりづらかったと思います。

index.mdの内容は以下のみで、記事としては存在しないセクションになっています。

---
headless: true
---

実際のファイル構成はimagesディレクトリの中に全ての記事画像が配置していました。

content/
├── images/
│   └── # ここに全ての記事の画像を配置していた
フロントマターに「headless: true」と書くことで、記事として表示しないコンテンツになります。

改善ポイント

「ファイル構成をシンプルに」「使える機能を正規の利用法で使う」 を目指してみました。

自分がやりたいことと、現状実装のギャップを見つけるところがまず大変でした。
PageBundleやassetsの他にも、記事ごとのURLの決定方法をどうするかなど、カスタマイズできるところが多いので、弄るポイントを絞ってやらないと収拾がつかなくなると思います。 記事の管理方法はHugoテーマ作成者によって様々なので、テーマを選ぶときはデザインに加えて、記事管理方法やHugoの機能が使いやすい実装になっているかどうかの吟味もしたほうが良いかもしれません。

コマンド一発でOGP画像を生成可能にした

https://github.com/Ladicle/tcardgen
こちらの公開元の説明通りに実行したのみです。
index.mdを読み込み、同ディレクトリにindex.pngを出力させています。

#!/bin/zsh

PROJECT_BASE=./
CMD=~/go/1.18.2/bin/tcardgen
FONTDIR=${PROJECT_BASE}/assets/font/candara-mp1code
CONF=${PROJECT_BASE}/tools/tcgconf.yaml

CONTENT_DIR=$1
IN=${CONTENT_DIR}/index.md
OUT=${CONTENT_DIR}/index.png

${CMD} -f ${FONTDIR} -c ${CONF} -o ${OUT} ${IN}
# この記事をOGP生成するためのコマンド
./ogpgen.sh content/posts/site_updating_202301
この記事のイメージ画像も同様の方法で出力させていますが、tcardgenはフロントマターのtitle部分を出力するため、titleを一時的に「Cafe Des Angolmois 2023」に変更した上で生成しました。

Image Processingでビルド時に画像加工するようにした

記事の全ての画像はビルド時に自動生成されますが、HugoのImage Processingの機能には、画像に対して別の画像や文字をオーバーレイ表示させる機能があります。

実験的に、画像の左下にサイト名のウォーターマークを埋めこんでみました。
テンプレートにコードを書いておけば自動で処理してくれるので便利ですね。
他に良い使い道があればまた紹介しようと思います。

{{ $img := .Page.Resources.Get (.Get "src") }}
{{ if $img }}
    {{ $font_size := div $img.Height 26 }}
    {{ $y := mul $img.Height 0.92 }}
    {{ $x := mul $img.Width 0.02 }}
    {{ $font := resources.Get "/font/MPLUSRounded1c-Regular.ttf" }}
    {{ $img = $img.Filter (images.Text .Site.Title (dict "font" $font "color" "#ccccb0" "size" $font_size "linespacing" 2 "x" $x "y" $y))}}
    {{ $imgLink := $img.RelPermalink }}{{ .Scratch.Set "imgLink" $imgLink }}
{{ else }}
    {{ $imgLink := resources.Get "/images/index.png" }}{{ .Scratch.Set "imgLink" $imgLink.RelPermalink }}
{{ end }}
{{/* リンクとして使う場合は以下のように呼び出せば良いです */}}
<a href="{{ .Site.BaseURL }}{{ .Scratch.Get "imgLink" }}" class="d-block" data-toggle="lightbox" data-gallery="post-gallery">
<img src="{{ .Site.BaseURL }}{{ .Scratch.Get "imgLink" }}" />
</a>
このコードは当ブログで使用している画像表示のショートコードの一部です。
images.Text でサイト名を埋め込んでいます。
resources.Get で指定しているパスは /assets 内のファイルが参照されます。

まとめ

以上が今回の改良内容の要約です。
そもそもで改良しようと思ったきっかけは、楽してブログにポストする運用環境を構築したかったからです。 今回の改良で概ね目的は達成されました。

  1. コマンドでMD記事テンプレを生成
  2. 記事を書く
  3. コマンドでアイキャッチ画像を生成
  4. GitへCommit->Push
  5. 記事の投稿日付になったら自動でBlogが更新される

1~4までの手順(実質手順2)を120分以内のサイクルで回すことができれば、安定運用できそうです。
そう、次に必要なものは発信力と文章力(笑)

Hugoは比較的短期間でアップデートされており、新しい機能実装に対しても積極的です。
勉強と紹介を兼ねて、Hugoネタは今後もこのブログで発信していければと思います。



関連記事