Featured image of post はてなブログからHugo記事に移行するためのスクリプトを作った

はてなブログからHugo記事に移行するためのスクリプトを作った

以下の記事でお知らせした通り、はてなブログで公開していたブログをHugoで作り直して、さくらのレンタルサーバーに移設しました。

これまで個人ブログをはてなブログで運用してきたのですが、本日をもって卒業し、Hugoによる静的サイトとしてさくらレンタルサーバーに引越しまし...
はてなブログからHugoベースの静的サイトへ移行しました

このとき、はてなブログの記事をHugoの記事構成とメタデータに合わせた形に変換する必要があったので、スクリプトを作成して対応しました。

A tool to convert a MovableType text exported from Hatena-blog to Hugo page bundles (Leaf Bundles). - GitHub - tomoyukim/hatena-movabletype-to-hugo: A tool to convert a MovableType text exported fr...
GitHub - tomoyukim/hatena-movabletype-to-hugo

自分のHugo構成などに寄った作りではありますが、特殊な構成でもないので、他の方でも利用していただけるかもしれません。 また、下記で紹介する通りJavaScript製なので簡単に修正して使っていただけると思います。

Hugoサイトの構成

Hugoの構成ですが、content以下に移行する記事を配置する post/ と、今後記事を配置していく entry/ とに分けてディレクトリを構成することにしています。 アーカイブなどのページは page 以下に配置します。

post 以下は、はてなブログの記事URLと同等の構成にします。はてなブログでは、「標準URL」を利用していたので、日付と記事のIDによる構成です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
content/
  page/
  post/
    2014/
      01/
      02/
	14/
	  123456/
	    index.md
	    images/
      ..
    2015/
    ..
  entry/
    slug/
      index.md
      images/
content-org/

スクリプト概要

このスクリプトは、MovableType形式でエクスポートされた各記事のメタデータをFront Matter形式に変換し、上記の post 以下の構成で出力します。

記事はHugoのLeaf Bundle形式で出力するようになっています。変換処理の際に、記事のBodyには以下のような処理を実施しています。

  • BodyのHTMLをできるだけMarkdownに逆変換
  • はてなフォトライフのimageを各bundleディレクトリの image/ 以下にダウンロード
  • Amazonのアフィリエイトリンクやはてなブログカードリンクはshortcodeへ変換
  • はてなキーワードリンクの削除

BodyのHTMLを変換しているのは、styleの適用などがおかしくなるケースを最小化できるよう、なるべくHugoのthemeに沿ったHTMLとして再生成させたかったからです。

特殊なリンク表示はHugoのshortcodeに変換しています。以下はブログカードリンクの例です。

{{% card url="https://…" img="https://…" title="…"%}} … {{% /card %}}

これは、あとでshortcodeで生成するテンプレートでどうにかしようと思っていたためです。 shortcodeにしておけば、最悪ただのリンクタグにしてしまうことから、凝ったブログパーツにすることも後でどうにでもできると考えています。

JavaScriptでシェルスクリプトを書きやすくする zx

zx はJavaScriptでシェルスクリプトを書くためのヘルパーです。今回作成した hmt2hugo スクリプトはこの zx ベースで作成しました。

zx は、Top level awaitfetch といったJavaScriptの便利な機能が利用できる他、 $`mkdir -p` といったシェルコマンドを簡単に記述できるシンタックスを提供してくれます。

本家リポジトリの導入文にも、

Bash is great, but when it comes to writing more complex scripts, many people prefer a more convenient programming language. JavaScript is a perfect choice, but the Node.js standard library requires additional hassle before using. The zx package provides useful wrappers around child_process, escapes arguments and gives sensible defaults.

とあるように、Node.jsなどの環境依存を問題としないケースでは、シェルスクリプトとして非常に使いやすいツールになっています。

A tool for writing better scripts. Contribute to google/zx development by creating an account on GitHub.
GitHub - google/zx: A tool for writing better scripts

Open Graph情報とブログカードリンク

ブログカードというブログパーツがあります。 例えば、以下は旧ブログに掲載していたブログカードリンクで、はてなブログではMarkdownで指定することで、このようなリッチなリンクを自動で作成してくれます。

このようなリンクの情報には Open Graph Protocoll(OGP) が使われています。

OGPというのは、元々はメタ社がFacebookでソーシャルグラフ表現のために策定していたHTMLヘッダーに任意のデータを記述するためのデータ形式のことです。 現在ではTwitterなどが読み取って表示に利用してくれたり、先のはてなブログでブログカードに利用されたりするので、サイトに埋め込まれているのを見かけることも多いのではないでしょうか。

Facebook_Platform/Open_Graph_protocol - Wiki

先でも触れたように、元々旧ブログではてなのブログカードとして掲載していたリンクは、できればそのまま記載したいと思っていました。 ただ、Hugoは静的サイトジェネレータですので、アクセス時にOGPを引く処理をしたり、スクレイピング用のサーバーを用意したりするのは避けたいなと思っていました。

そこで本ブログでは、記事作成時にOGPを引いてリンクを埋め込んでしまって、そのまま公開することにしました。 つまり、場合によってはいくつかのメタ情報が古い、もしくは画像がリンク切れする可能性があるということです。

画像はさておき、メタ情報については記事を書いたその時の情報を埋め込んでいる、という意味ではログとしては正しいと言える気がしますし、 OGPの更新やキャッシュに関する取り決めがあるわけでもないので、この運用でも問題ないかと思っています。

OGPの取得

hmt2hugo では、元々はてなブログのブログカードだったHTMLタグを変換する際に、リンク先のURLからOGPを取得してshortcodeに展開するオプションを実装しました。

1
./hmt2hugo.mjs ./path-to-exported-file --ogp

リンク先のURLからOGPを取得するには、HTMLタグのスクレイピングが必要です。しかし zx はあくまでシェルスクリプトなので、スクレイピングは他のコマンドで解析したいところです。

残念ながら、ちょうどよさそうなツールが見あたらなかったので、以下の記事で公開されていたURLからOGPをスクレイピングしてjsonでレスポンスしてくれるローカルサーバーを利用させて頂きました。

やりたいこと Hugo でブログカードを作成したい レスポンシブなデザインにしたい(スマートフォンで見たときに画像サイズ等を変更したい) レスポンシブなブ...
Hugoでレスポンシブなブログカードを作成する

従って、 --ogp オプションを利用する前には、以下のようにローカルサーバーを立てておく必要があります。これを hmt2hugo スクリプトが利用して、OGPが取得できればブログカードのshortcodeに変換します。 もし取得できなければ、通常のリンクになります。

1
2
3
cd get_ogp
npm i
node server.js

まとめ

はてなブログのエクスポート記事情報をHugo用に変換するスクリプトの紹介でした。

OGPの埋め込みなど、いくつか特徴的な機能を実装しましたが、shortcodeにしているので比較的汎用性を持たせられたかな?と思っています。(どうだろう。。。)

そのまま使えなくても、近年1、2を争う人気のJavaScriptで書いてあるので、(個人的には)細かいところは改変して使いやすくなっていると思います。 Hugoに移行したいな、と思っている人の助けになれば幸いです。

Built with Hugo
テーマ StackJimmy によって設計されています。