ブログをWordPressからHugoに移行した。

いろいろな理由があるのだけど、記事をテキストファイルで扱えるというのと、なんだか面白そうだったからというのが大きな理由。
ブログ記事程度のものをわざわざ動的に生成するのも馬鹿らしいなあという気は前からしていて、静的サイトジェネレータには興味があった。

Hugoはサイトを生成するだけで、アップロードの面倒までは見ない。なのでGitとフックスクリプトを使って、リモートリポジトリのmasterブランチにpushしたらサイトが更新されるようにした。

これらの作業はひとりでやってしまったので、自分しかブログの書き方がわからない。それでは困ると言われたので、書き方を記事にまとめておく。
なお、面倒くさいのでブランチについての説明は省く。とはいえブランチこそがgitの真価とも言えるわけだが……

準備

gitで管理しているので、作業を始める前にHugoブログのルートディレクトリ(以降$HUGOROOTと呼ぶ)に移動し、git fetch + git merge FETCH_HEADをする。まとめてgit pullでもよい(GUIのgitクライアントでは、pullのほうが目立つところにあるはずだ)。これは、よそで行われた(正確にはリモートリポジトリにある)変更を取り込むための行為だ。

参考:

マンガでわかるGit 9話「pullの正体はfetch+mergeだった?」|CodeIQ MAGAZINE

新規記事

hugoコマンドも、この$HUGOROOTから行う。

hugo new セクション/タイトル.md

このブログではいまのところセクションは「post」ひとつしかない。また、ファイル名は管理のしやすさからYYYY-MM-DD形式の日付で始め、タイトルには自動で挿入されないようにしている(タイトルはだいたい後からつけるからだ)。

よって、

hugo new post/`date +%Y-%m-%d`.md

を実行すると、特に何も考えずに新規記事を作成することができる。

--editor="EDITOR"オプションをつけることでそのまま編集もできる。たとえばVisual Studio Codeで編集したい場合は

hugo new post/`date +%Y-%m-%d`.md --editor="code"

とやればよい。

編集

静的なデータの置き場所

画像など、Hugoが手を加えないファイルは$HUGOROOT/static/以下に置く。このディレクトリの中身は、サイト生成時にそのまま(ディレクトリ構造も含めて)ルートディレクトリ直下にコピーされる。わかりやすい構造にしておくことが望ましい。

フロントマター

新しく作成された記事をみると、はじめに---1で囲まれた行があることに気づくだろう。これはフロントマターと言われるもので、その記事についてのパラメータを記述するものだ。

ほとんど見れば分かるものだが、いくつか解説があったほうが良いものがある。

サムネイル

記事のサムネイルを指定する。サムネイルには3種類の指定方法がある。

静的データを指定する
thumbnail: "/PATH/TO/IMAGE.jpg"

パスは$HUGOROOT/static/から見た相対パスで記述する。

Flickrのページを指定する
thumbnail: "https://www.flickr.com/photos/USERID/PHOTOID/"
画像ファイルのリンクを指定する
thumbnail: "//HOST/PATH"

スキームは省略してよい(しなくてもよいが、その場合でも内部で切り捨てられる)。

下書き

draft: true

これがtrueになっていると下書き状態ということになり、サイト生成時に無視される。記事を公開する際にはfalseになっていなければならない。

プレビュー

Hugoにはウェブサーバーが内蔵されており、これが非常に強力なリアルタイムプレビューとして機能する。

hugo server -D

と実行し、指定されたアドレスを開けばよい(-D--buildDraftsの短縮形で、下書き状態の記事も表示される)。リアルタイムプレビューなので、記事ページを開いておけば保存のたびに更新される。

ショートコード

Hugoにはショートコードと呼ばれる機能がある。定形のHTMLコードを展開してくれるものだ。Hugoやテーマに内蔵されているもののほか、自分で作成することもできる。

ショートコードは{{< コード名 引数 >}}または{{% コード名 引数 %}}のようにして書く。
このふたつは「閉じコード」のあるショートコードの際、異なる挙動をする。%%にした場合、挟まれた文字列はMarkdownとして解釈される。

Hugoに内蔵されているショートコードの一覧はHugo | Shortcodesにある。
youtubetweet、それに内部リンクを展開するref/relrefあたりが有用だろうか。詳しくは上記リンクを見てほしい。

公開、あるいはgit関連のあれこれ

何度も言うように、このブログ(正確にはそのソース)はgitでバージョン管理をしている。そのため、公開にあたってはgitの操作が必要になる。

コマンドラインから直接gitを叩いてもよいのだが、とくにステージング周辺はGUIのクライアントを使用したほうが分かりやすいと思われる。が、個別の操作についての解説はしない。

公開の前に

フロントマターのdraftをfalseにするのを忘れずに。

ファイルを管理対象に加える、または変更をステージする

「ステージ」についての説明は難しいが、「新しいコミットを作成する前に必要な予約」のことだと思えばよい。「この変更は次のコミットに含める」という準備作業だ。
この予約の領域を「ステージング領域」と言ったり「インデックス」と言ったりする。

すべての変更は、まず「ステージ」されなければいけない。新しくファイルを作成したときも同様だ。

git add FILENAMEで、そのファイルについての変更が「インデックス」に入る。

ちなみに、作成も含めた変更をまとめてステージする際はgit add .とやる。

コミットの作成

「コミット」は簡単にいうと、スナップショットだ。それぞれのコミットは「親が誰か」という情報を持っていて、それが積み重なることで、履歴になっているというわけだ。

さて、インデックスにある変更をコミットとして登録する2には、git commitだ。しかしこれを入力するのは少し待ってほしい。

コミットには「どんな変更点を加えたか」というのを示すコミットメッセージというものを添えるのが普通で、特に指定しないで「コミットし」ようとすると、これの入力をvimで3求められる。常人にはつらい。

なので、

git commit -m 'hogehoge'

と、一緒にコミットメッセージも書いてしまうといい。-m--messageの短縮形だ。

リモートへのプッシュ

操作としては、これが「記事の公開」ということになる。ズバリ、git pushだ。これは、ローカルリポジトリにあるコミットたちを、リモートリポジトリに送信する行為だ。

冒頭に言ったように、「中央」リポジトリが変更を検知すると、Hugoのビルドが始まり、その成果物が公開用ディレクトリにrsyncされるようになっている。
それらのログはpush時に一緒に表示される。正常に終われば、記事が公開されているはずだ。

おわりに

Hugoの記事作成にかかわる部分だけに絞ったものの、やはりgitについては分かりにくくなってしまった。内部の仕組みを置いておいて、とりあえず説明するというのが難しい。

参考

仕組みについてはこのサイトが詳しい。


  1. YAMLの場合。TOMLなら+++、JSONなら[]で囲まれている
    ↩️
  2. この行為を「コミットする」という。「コミット」には名詞と動詞があるのだ! gitは用語が分かりにくい。
    ↩️
  3. EDITOR環境変数を変更しているような人のことは知らない。
    ↩️