この記事は「はてなブログからの静的ウェブページへ移行まとめ(前編)」の続きになります。読んでない方は前編から読んでみてください。

さて、この記事では、はてなブログからHugoへの移行の技術的な側面をカバーしていきます。プログラムやコマンドがたくさん出てきますので、予めご了承ください。なお、ブログ主はMacユーザーですのであしからず。

既存ブログ記事の移行

はてなブログからデータをエクスポートすると、example.hatenablog.com.export.txtと言った名前の巨大なテキストファイルがダウンロードされると思います。

これをそのままHugoには持っていけませんので、変換プログラムが必要となります。

私の場合は、これをRubyで自作しました。以下のgithubで公開してあるので、自己責任でご自由にお使いください。前提として、プログラム言語Rubyのインストールが必要になります。

以下、データ移行上の技術的ポイントをいくつか挙げていきます

マークダウン? or HTML?

example.hatenablog.com.export.txtの中身を実際見てもらえれば分かりますが、本文の中はマークダウン形式ではなく、htmlそのものになっているんですね。それをどうHugoに持っていくか、というのが悩みどころなのですが、簡単な解決策がありました:

Hugoではフロントマターを付けてhtmlファイルとして保存すれば良い

つまり、以下のようなファイルを作成し、htmlファイルとして保存すれば、Hugo内でコンテンツと認識してくれるのです。これに気づくのに結構時間が掛かりました(笑) 

---
title: "Test"
date: 2020-08-14T00:31:15+09:00
categories:
- test
---
<h1>Test</h1>
<p>This is a test article.</p>
...
...
...

URLの整合性

次に、はてなブログ時代のentry以下のURLの構造をどうやってHugoに持っていくかを悩みました。結局、URLは新規構造にし、旧URLにアクセスした際に新規URLに飛ばすという仕組みにしました。これは、Hugoのフロントマター内のaliasesで実現しています。

hb2h.rb
  • ruby
1
2
  RedirectFlag = true #新URLにリダイレクトさせるか。trueの場合、フロントマターにエイリアスを追加
    

新旧記事フォルダの棲み分け

私が選んだテーマtranquilpeakの制限で、post配下に記事を入れる必要があったので、以下のように移行データと新規分データでディレクトリを分けることにしました。移行分に関しては上記プログラムで処理した後はノータッチです。

content
└── post
    ├── entry (はてなブログから移行したデータ、html拡張子)
    └── blog (新しく書き始めた記事、md拡張子)

テーマ専用独自処理

テーマtranquilpeak用に独自の処理を移行プログラムに入れてあります。例えば、以下はtranquilpeakが独自に持つthumbnailImageフロントマターの内容をIMAGEエントリに指定してる箇所。はてなブログで指定していたサムネイルURLはIMAGEエントリに入る仕様でした。

hb2h.rb
  • ruby
1
2
3
  #Hugo非標準(テーマ依存)のFront Matter
  "IMAGE" => [StrFld, "thumbnailImage"],
    

このように、選んだテーマによっては、独自の処理を追加する必要があるかもしれません。テーマの説明を熟読することをおすすめします。

続きを読むの処置

はてなブログ時代に<!-- more -->タグを利用したことある人はハマるんですけど、このタグの前後で本文のエントリがBODYとEXTENDED BODYに分割されるんですね。それは注意が必要です。

自作プログラム内では、最後に結合する処理にしています。

hb2h.rb
  • ruby
1
2
3
  "BODY" => [BodyFld],
  "EXTENDED BODY" => [ExtendedBodyFld],
    

Hugoとテーマのインストール

Hugoのインストール自体は、ターミナル上で以下のコマンドを打てばOKです。なお、brewがインストールされている前提です。

brew install hugo

次にサイト作成ですが、適当なディレクトリで以下のコマンドを打ちます。site-nameは自分で好きな文字列にしてください。すると、必要なファイルやディレクトリ等が作成されます。

hugo new site site-name

詳しくは https://gohugo.io/getting-started/quick-start/ 参照。

次にテーマですが、自分の気に入ったテーマを探してきて、そのテーマの説明を参考にインストールします。基本的には、hugo new siteで作られたディレクトリにthemesというディレクトリができていますので、そこにテーマのファイルを保存すればOK

テーマは以下のところから一覧で見られます。

JAMstack Themes⤴️

記事の書き方

ターミナルを起動し、2窓にして、上記で作成したサイトのディレクトリに移動します。そこで、まず以下のコマンドを打ち、ローカルでWebサーバーを起動します。

hugo server -D

http://localhost:1313/ でアクセスできるようになっていると思います。

次に、ようやく記事作成です。

ターミナルの別窓で、以下のコマンドを打ちます。すると、テンプレのマークダウンファイルが作られます。(なお、これはtranquilpeakを選んだ私の場合で、テーマによってディレクトリ構造は異なると思います)

hugo new post/blog/my-first-post.md

作成されたmy-first-post.mdをお好みのエディタで開き、記事を書いていきます。当然、マークダウンです。なお、テーマによってはフロントマターが拡張されていて、細かい設定ができたりするので、テーマのフロントマターの説明はじっくり読んだ方がいいでしょうね。

例えば、今使っているtranquilpeakには

thumbnailImagePosition: right

というフロントマターが独自に追加されていて、デスクトップPCで記事一覧を見ると、サムネイルが右に表示されたりします(笑)

最後に、記事を書き終わったら保存して、ブラウザ上で出来を確認します。http://localhost:1313/ にアクセスしましょう。なお、おすすめは、記事を書きながらもブラウザでlocalhostは常時開いておくと便利です。どういった感じか、すぐに確認できますので。それに、エディタでマークダウンファイルを保存すると、即座にブラウザ上のページも再読み込みが発生するという親切設計になってたりします。はてなブログで言うところのプレビューみたいなものですね。

記事の推敲が終わったらいよいよ静的ウェブの生成です。ローカルで起動しているサーバを止め、

hugo --gc --minify

でファイルを生成します。publicというディレクトリ直下に必要なファイルがすべて入りますので、これをそのままレンタルサーバにアップロードするだけです。

Hugoでの静的ファイルの置き場所

Hugoではcssやサイトのデフォルトアイキャッチ画像なんかはstaticフォルダの下に入れておくことになってます。css、JavaScriptはそちらに入れておきましょう。なお、私の場合はグーグルアドセンスを使っているため、ads.txtもそこに入れてあります。

サーバとの同期

次に、サーバとの同期について。

FTPが駄目な理由

まず、FTPは絶対やめましょう。セキュリティを向上したSFTPとかありますけど、それ以前の問題です。とにかく遅い。差分更新とかできないみたいで、サーバ側にも依存しますが、自分がやってたときには、平気で30分とかかかっていました。静的サイト生成でブログする場合は以下に述べるRcloneを使ったほうがいいですね。

Rcloneインストール

これもbrewを使います。

brew install rclone

なお、実は当初は同様の同期ツールrsyncを使っていましたが、相性が悪く同期されなかったようなのでやめた経緯があります。

Webdav経由でRcloneで同期

まず、サーバがWebdavを使えるか確認しましょう。私が申し込んだロリポップでは幸い対応していたので、以下Webdavで説明していきます。

なお、Rclone⤴️はいろいろなプロトコルに対応していますので、Webdav以外でも使えるはずです。レンタルサーバ側の対応プロトコルと、Rcloneのマニュアルを確認してみてください。

Rcloneのconfig設定

Rcloneには頻繁に同期を取る遠隔サーバに関しては、config設定をすることでエイリアスを使えるようになっています。これをぜひ使いましょう。

https://rclone.org/webdav/

以下、Webdavの例でconfigの設定の仕方を説明します。なお、このconfig設定だけは何故かインタラクティブな親切設計です(笑)

まず、ターミナル上で以下のコマンドを打ちます

rclone config

3つの選択肢が聞かれますのでnを選択し、新規にサイト登録します、

No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n

名前の入力を求められますので、自分のサイトの名前でもなんでも、わかりやすい文字列を入力します。これがエイリアスになります

name> test

デフォルトで設定されたストレージ一覧が出てきますので、webdavを入力します。

33 / Union merges the contents of several upstream fs
   \ "union"
34 / Webdav
   \ "webdav"
35 / Yandex Disk
   \ "yandex"
...
Storage> webdav

アクセス先の入力を求められますので、レンタルサーバから与えられたwebdavのurlを入力します。

URL of http host to connect to
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
 1 / Connect to example.com
   \ "https://example.com"
url> レンタルサーバから与えられたwebdavのアクセスurl

ベンダーはlolipopなので、当然other(笑)。Nextcloudとか使ってる人はそっちを選択してください。なお、数字で入力してもOKです。

 1 / Nextcloud
   \ "nextcloud"
 2 / Owncloud
   \ "owncloud"
 3 / Sharepoint
   \ "sharepoint"
 4 / Other site/service or software
   \ "other"
vendor> other

ユーザー名を入力。レンタルサーバから与えられたもの。

User name
Enter a string value. Press Enter for the default ("").
user> user-name-given-by-the-vendor

次はパスワード。

Password.
y) Yes type in my own password
g) Generate random password
n) No leave this optional password blank (default)
y/g/n> y

パスワードの入力です。確認用と2回入れます。

Enter the password:
password:
Confirm the password:
password:

Bearer tokenを聞かれますが、特にないのでそのままエンターを押します。空文字がセットされます。

Bearer token instead of user/pass (eg a Macaroon)
Enter a string value. Press Enter for the default ("").
bearer_token>

アドバンスの設定をするか聞かれますが、特に必要ないのでnを選択。

Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n> n

最後に確認画面が出てきます。この内容で問題ないならyを選択。

[test]
type = webdav
url = https://example.com
vendor = other
user = user-name-given-by-the-vendor
pass = *** ENCRYPTED ***
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y

以上で設定が完了です。これ以降は、testというエイリアスの名前で、この設定にアクセスできます。

Name                 Type
====                 ====
test                 webdav

最後に、サーバとローカルのpublicディレクトリとの同期コマンドを入力します。一度configの設定を終えておけば、次からはこのコマンドを打つだけでOK になります。-Pは進捗情報を出力するスイッチです。

コマンド書式:
rclone sync ローカルのディレクトリ エイリアス:サーバ側ディレクトリ -P

例:
rclone sync user/site-name/public/ test:public/ -P

日々改善

ブログ記事を書いていると、よく出てくる全く同じ処理というものがあります。こういうときこそ、Hugoの超強力な構造化推進機能ショートコードの出番です。

https://gohugo.io/content-management/shortcodes/

自分独自のショートコードを作ると、記事作成が格段にしやすくなります。また、htmlフリーにすることができます。

また、日々使っているとテーマのデザインなどでちょっと不満な点なども出てくるかと思います。そこも、Hugoでは利用者側で上書きできますので、themesディレクトリの下を眺めてみるのも面白いと思います。

なお注意点ですが、テーマ作成者が作ったファイルを直接いじるのではなく、layoutsディレクトリにそれと同じファイルを作るのがポイントです。というのも、Hugoではlayoutsディレクトリにあるものが優先されるためです。この辺は、上級コースになりますかね(笑)

以上になります。今回は長くなりましたが、お付き合いありがとうございました。

私がお世話になってるロリポップさん↓