第5回 Movable Type の日記を Hugo に移す
:2004年から書いていた日記を、Movable Type(MT)から Hugo に移しました。
日記は MT で書いていて、記事は古いサーバーの MySQL に入っていました。 しばらく更新していなかったのですが、サーバーの引っ越し(第3回)にあわせて、 過去の記事を救出して、また書けるようにしたい、というのが今回の作業です。 作業は Claude(生成AI)と一緒に進めました。
まずはデータベースを取り出す
古いサーバーの MT のプログラムはもう消してあって、残っているのは MySQL の中身だけ。 しかも FTP しか使えず、phpMyAdmin のような管理画面もありません。 そこで、データベースの中身をファイルに書き出す小さなスクリプトをアップロードして、ブラウザから実行することにしました。
- 最初は PHP で書いたのですが、つながらない。 古いサーバーの MySQL ユーザーのパスワードが、MySQL 4.1 より前の古い形式で保存されていて、 今の PHP(mysqlnd)は安全のためその形式を受け付けないためでした。
- 古いサーバーの Perl(5.8.8!)の DBI なら古い形式でもつながったので、Perl の CGI で書き直して、無事に書き出せました。 記事が 1,383件、コメントが 490件。
- 使い終わったスクリプトは、すぐにサーバーから消しました。(データベースのパスワードを読むスクリプトなので、置きっぱなしは危険です)
文字化けの正体は「二重エンコーディング」
書き出したデータを見ると、日本語が文字化けしていました。
調べてみると、テーブルの文字コードの設定は latin1(英語圏向け)なのに、中には UTF-8 の日本語がそのまま入っていました。
いわゆる二重エンコーディングです。
昔の MT と MySQL の組み合わせでは、よくあったことらしいです。
この状態で「UTF-8 でちょうだい」と言って取り出すと、MySQL が気を利かせて
「latin1 の文字を UTF-8 に変換」してしまい、すでに UTF-8 だったものがもう一度変換されて化けます。
そこで、変換せずにバイト列のまま(binary で)取り出しました。
my $dbh = DBI->connect("DBI:mysql:database=...;host=localhost", $user, $pass);
$dbh->do("SET NAMES binary");
こうして取り出したバイト列は、そのまま UTF-8 として読めば正しい日本語でした。
WordPress ではなく Hugo にした理由
新しい日記の仕組みは、WordPress と Hugo で迷いましたが、Hugo にしました。
- Hugo は手元の PC で HTML を作って、それをアップロードするだけ。 サーバーでプログラムを動かさないので、データベースも PHP もいらず、乗っ取られる心配もほとんどありません。
- 記事が1記事1ファイルのテキスト。バックアップが簡単で、何十年後でも読めます。
- その代わり、コメント欄は作れません。(昔のコメントは表示だけしています)
MT の記事を Hugo の形に変換する
取り出したデータを、Hugo 用のファイルに変換する Python スクリプトを作りました。やっていることは次のとおりです。
- 公開中の記事だけを、1記事1ファイルにする(本文は MT 時代の HTML のまま)
- MT の「改行を自動で <p> や <br> にする」機能を同じ規則で再現する
- URL は MT 時代のままにする。昔の記事にリンクしてくれているページがあっても、リンク切れになりません
- コメントは、表示されていたものだけを入れる(メールアドレスや IP アドレスは入れない)
- 記事で使っている画像のうち、昔のサーバーに残っていたものをコピーする
MT 時代の一部の URL は .php で終わっていたので、.htaccess で新しい .html の URL へ転送しています。
Hugo でハマったところ
-
HTML のままの記事が読み込まれない。
Hugo は普通は Markdown で記事を書くものなので、拡張子
.htmlの記事は、設定で許可しないと読み込んでくれません。# hugo.toml [security] allowContent = ['! ^text/org$'] -
転送先が変な URL になる。
/~arai/のようなユーザーディレクトリで.htaccessの転送を使うと、 転送先にサーバー内部のフォルダのパスがくっついてしまいました。RewriteBaseで基準の URL を書いておくと直ります。RewriteEngine on RewriteBase /~arai/mt-diary/ -
メニューのリンクがサイトの外に飛ぶ。
Hugo のテンプレートで
"/archives/" | relURLのように先頭に / を付けて書くと、/~arai/mt-diary/の部分が付かず、サーバーのトップからの URL になってしまいました。 先頭の / を外して"archives/" | relURLと書くのが正解でした。 -
改行が無視される。
Markdown では、1回の改行は前の行とつながってしまいます。
日記は改行したところでそのまま改行してほしいので、設定で変えました。
[markup.goldmark.renderer] hardWraps = true
書くのも、公開するのも楽に
- 日記を書く画面。 Markdown の書き方をよく忘れるので、ボタンで見出しや太字を入れられて、横でプレビューが見られる、 ブラウザで動く自分用のエディタを作ってもらいました。カテゴリやタグも入れられます。
- 公開はバッチファイル1つ。 ダブルクリックすると、Hugo で HTML を作って、サーバーとの違いを一覧で見せてくれて、「y」を押すと WinSCP でアップロードしてくれます。 手元で消した記事は、サーバーからも消えます。
振り返り
- 古いデータは、取り出し方で化けたり化けなかったりする。 文字化けしたら、「データが壊れている」と決めつける前に、取り出すときの変換を疑うといいです。
- URL は変えない。 昔の記事の URL をそのまま残せたのが、今回いちばんよかったところです。
- 静的サイトは気楽。 サーバーで何も動かないので、セキュリティの心配がぐっと減りました。
2004年からの日記が、また読めるようになりました。これからは技術メモ中心に、また書いていこうと思います。
以上、です。