WordPress から Hugo への乗り換え

6 min読了の目安(約5600字TECH技術記事

Zenn も使ってみようということで初記事作成。

WordPress から Hugo への乗り換えというネタは、当然あちこちにありますが、意外と色々なパターンがあるので、以下のパターンについて、記録を残しておきます。

  • WordPress to Hugo Exporter でのデータ出力
  • テーマは、「Mainroad」
  • GitHub Pages のタイプは、「GitHub Pages project」
  • 年別アーカイブ widget 追加

作成したサイトはこちらになります。
PROGRAMMERS OFFICE

WordPress to Hugo Exporter でのデータ出力

移行元の WordPress からのデータ出力は、WordPress to Hugo Exporter を使用しました。
これ自体は、プラグインをインストールして、メニューから
ツール > Export to Hugo
をクリックすると、おもむろに、ZIPファイルダウンロードが始まります。

ただ、最初これがエラーになってしまいました。
原因は、環境のパワー不足。
記事自体は778記事、4.7MBという程度のものでしたが、画像等も含めて、展開した結果のファイルサイズは234MB。
これを出力するために、GCPの無料枠「f1-micro」では処理しきれませんでした。
ここはクラウドの利点を活かし、いったんマシンタイプを変更して、ダウンロード後に戻す、ということで対応しました。

Hugo へのデータ取込

取込時エラー

Hugo 自体のインストール等については、多数情報があるので割愛します。

移行元からダウンロードしたZIPファイルを復元(最近は解凍と言わないらしいですね)してできるフォルダ「hugo-export」の中の「posts」に778個のファイルが入っています。
とりあえず、これをこのまま、Hugo で作ったサイト構成の中の、content の中にコピーすることにより、表示されるはずですが、エラーになりました。
記事のタイトルの先頭に「@」を使用しているとエラーになるようです。
逆に、起動しないレベルのエラーはこれ一つということで、移植性は高いです。

階層分け

また、1フォルダに778このファイルが存在するのも扱いにくいので、年ごとのフォルダに分けることにしました。
2003年から2020年まで(なぜか途中跳んでいる年もありますが)。最近は少ないですが、よく続いています。
これは後で効いてきます。Hugo 的には、content 配下の階層は気にしない(セクションとして扱われますが)ということで、ありがたいです。

不要行削除

また、エラーではありませんが、表示されない情報等があります。
出力されたmdファイルの記述の中で、pタグとかdivタグ付きで出力されているものがあります。
このタグ間に空白行が含まれていると、表示されなかったり、タグがそのまま表示されたりします。
これを一括置換します。
VSCode使用が前提ですが、

>\n    \n    <

>\n    <

に置換する、というようなことをします。
閉じタグの後ろにスペースがある場合もあるので

> \n    \n    <

と指定したりもしますし、先頭のスペースの数も、4つだったり6つだったり色々あったので、各パターンで置換していきます。

画像リンク

画像ファイルもちゃんとダウンロードされているので、それを static フォルダ配下に入れました。
それの参照もできるのですが、どうも、画像のリンク記述が、

<img src="https://i2.wp.com/

というような記述になっている。

「i2.wp.com」とは?ということで調べると、WordPress でJetpackを入れていると、このサイトでキャッシュをしてくれていたということです。やめる時に初めて知りました。

本当は、これも一括置換すれば良いわけではありますが、いったんは、ありがたく、そのまま使わせていただいています。

Hugoテーマ選択

テーマ選択は悩むと思います。
最初は、「hugo-theme-learn」をインストールしてみました。

左ペインの盛りだくさん感は好きなのですが、素人には若干敷居が高そうな気がしたので、これまでのブログとも表現が近いと感じた「Mainroad」にしました。

その設定方法等については、下記のサイトにお世話になりました。

HUGOのテーマ「Mainroad」の設定方法を紹介

Hugo によるブログ作成と mainroad テーマのカスタマイズ

テーマを切り替えて最初は、

まだ何も投稿していません!
content 以下のどこかのディレクトリに投稿を追加するとここに表示されます。デフォルトでは(最も投稿の多い)1つのセクション だけがメインページに表示されます。

ヒント: 設定のパラメーター mainSections を使って好きな数だけセクションを表示させることもできます。

という画面が表示されて、なんだろう、と悩みましたが、いったん、公式のConfig.toml exampleを適用すると表示されました。

そこからあれこれ調べながら、設定値を変更して、現在この見た目になっている、ということです。
(ただし、「アーカイブ」ウィジェットについては後述)

GitHub Pages へのデプロイ

デプロイ先も、本当は、最近よくお世話になっているNetlify が楽ではないかなと思ったのですが、あえて楽すぎない道を選ぶということで、GitHub Pages にしました。

そうなったときに、まず決断を迫られるのが、

  • GitHub Pages project (プロジェクトサイト)
  • personal/organizational site (ユーザサイト、組織サイト)
    のどちらのタイプにするか、です

のはずですが、初めて作ろうという私は、情報のある方に従わざるを得ない立場。

GitHub Actions による GitHub Pages への自動デプロイ
こちらのサイトのやり方を使わせていただきます。

が、これはどちらのタイプ?ということがちょっと分かりにくい気がしました。
これは、プロジェクトサイトになります。

https://ユーザ名.github.io/リポジトリ名/

というURLになります。

手順は以下のようになります。
(1) .githubでリポジトリ作成、ソースpush
push前に.gitignore作成も。

.DS_Store
public/

(2) .github/workflows/gh-pages.yml 作成・push
基本的には書いてある通りです。
hugo-version を今回インストールされた、0.79.0 にしたのみです。

(3) GitHubリポジトリのSettings内 GitHub Pages の設定
上記 gh-pages.yml が実行されることにより、gh-pages というブランチが作られるようです。
プロジェクトサイトを作る場合は、Source として、このブランチを指定します。

ブランチのソースを見てみると分かるように、いきなり各記事のフォルダが見ている状態ですので、(root)を指定します。
これにより、公開されたURLが表示されます。

これでURLを開いてみるわけですが、スタイルが当たっていませんし、記事を見ようとしてもリンク切れです。
なぜなら、プロジェクトサイトの場合は、Hugo上のルートがリポジトリ名の下からになるからです。
これへの対処のために、config.toml の先頭、baseURLを

baseURL = "https://jqinglong.github.io/programmers-office/"

のようにします。

これでいったん、移行完了というところでしょうか。

アーカイブwidget

ただ、一つだけ物足りないのが、過去の記事にアクセスするためのリンクがないということです。
カテゴリや、タグのウィジェットは自動的に作られているのですが、年とか月とかを指定した記事表示ができないのです。
ニーズありそうなものですが、みなさん苦労して対応されているようです。

最初は年ごとにフォルダ分けたので、そのセクションという考え方を使ってできないかなと思いました。
が、結論としては、Hugoで用意されている、taxonomiesのarchivesを使うことにします。

最初はこちらで、やることを掴みます。
Hugoで月別アーカイブを作る

ただ、若干細かいところが省略されている気がするので、下記も参照しました。
Hugo - Taxonomyを使ってアーカイブページを作る

手順は下記のような流れです。
(1) config.tomlにtaxonomiesの定義を追加
上記サイトのように、tag、category、archive 三つとも追加しておきます。
合わせて、sidebar に、archives ウィジェットを追加します。

[Params.sidebar]
  home = "right" # Configure layout for home page
  list = "right"  # Configure layout for list pages
  widgets = ["search", "recent", "categories", "taglist", "social", "languages", "archives"]

[taxonomies]
  tag = "tags"
  category = "categories"
  archive = "archives"

(2) ウィジェット定義ファイル作成
themes/mainroad/layouts/partials/widgets/categories.html
をコピーして、
layouts/partials/widgets/archives.html
を作成します。
メイン部分のulタグ内は、上記サイトの記述を利用させていただきました。

{{- $archives := .Site.Taxonomies.archives }}
{{- if gt (len $archives) 0 }}
<div class="widget-archives widget">
	<h4 class="widget__title">アーカイブ</h4>
	<div class="widget__content">
    <ul>
      {{ range $items := .Site.Taxonomies.archives.Alphabetical.Reverse }}
        <li><a href="{{ $.Site.BaseURL }}archives/{{ .Name | urlize | lower }}">{{ .Name }} ({{ .Count }})</a></li>
      {{ end }}
    </ul>
	</div>
</div>
{{- end }}

他言語化も難しくはないですが、日本語ベタ書きしています。

(3) 各記事に archives の記述追加
流石に、700ファイルに一つずつ入れていくわけにはいきません。
VSCodeで範囲指定一括置換できるので、それで各年のフォルダごとに、置換していきます。

\nurl: 

から

\narchives:\n    - 2004\nurl: 

という感じです。

所感

最大のメリットは、VSCodeから離れることなく、執筆から投稿までできるというところでしょうか。
作ったブログの Lighthouse スコアも高いです。
しばらく使ってみます。