2015-05-06

このサイトをTumblrからHugoに移行した

** この記事は古いです。現在はHugoを使用せず、自分で書いたスクリプトでブログを作ってます。 **
(追記:2016/06/22)

毎度毎度思っていたことではあるんだけど、Tumblrの使いづらさに我慢できなくなってしまった。 あれはブログ用途に使うもんじゃない。自分の好みにあったタイムラインを見て楽しむには良いけど (その用途ではとんでもなく楽しい)、 デザインを好みのものにカスタマイズするとか、独立したページを作るとかには弱いし、 記事投稿用のテキストボックスはいつでも崩れてる。もう我慢ならんと思って昔のnanoc時代に戻ろうかと考えていた。

調べてみると、Hugoという静的サイトジェネレーターが妙に人気があるようだ。 たくさんの人が移行している。

移行しすぎである。どんだけ人気なのだ。

なぜHugoか

ぶっちゃけ動作が速いということに尽きる。Rubyで実装されたJekyllが静的サイトジェネレーターとして有名だが、 まぁかなり遅い。Hexoとかは速いみたいだけど、node.jsも飽きたのではやりのGo言語で作られているからHugoにしてみた。 ようするの速ければなんでも良かったといえば良かった。

tumblrから記事をエクスポートする

まずはHugoでサイトを生成するためには、Markdownなどの形式で過去の記事を持ってくる必要がある。 問題はtumblrがそもそも記事を汎用的な形式で出力する機能がない。 APIを叩けばJSON形式で受け取れるが、そのためのスクリプトを書くのもなんだかめんどくさい。

「tumblr posts export」などで検索するといくつかのツールがヒットするが、 試してみたところ大抵はイマイチなものがおおかった。 なのでもう少しいろいろ見て回ると、 gistとして誰かが簡易的なミグレーションスクリプトを公開していた。 これをすこし変えて使うことにした。 そのままだと英語記事に付くslugタイトルがファイル名にされてしまう。 なのでここの部分はtumblrの記事IDを使おう。単純なRubyスクリプトだけど、とても有効に動いた。 実際のところ全ての記事が完璧なMarkdown形式に変換されたわけではないけど、 まぁMarkdownはHTMLべた書きでも動くので別に問題はない。 tumblrのAPIではmarkdown形式で記事を投稿しても、その記事はHTMLになって提供されてしまうのだ。 諦めよう。

tumblrにはテキスト記事だけではなく、quoteやphotoやmovieなんかも投稿できる。 私はほとんど使っていなかったが、Hugoに移行するにあたってこれらも同一のフォーマットにする。 内容はyoutubeの動画を埋めこんだりしていた程度だったので、それらの記事は削除した。 photo形式の投稿は思いのほか数がおおかったため、記事の内容とともに写真をダウンロードし、 改めて記事の形式に編集しなおした。休日にまとめて作業したけど、こういうあんまり頭を使わないちょっとした作業を 昼間からビールを飲みながら陽光差し込む明るい部屋でやると贅沢な感じがしてとても良い。

Hugoでサイトデザインをつくる

上で挙げた記事のほとんどはテーマをダウンロードしてきて使っているようだ。 もちろんそれでもいいんだけど、せっかくなので今回は1から作ってみた。 カラフルなのはやめてシンプルに色を減らした感じでつくった。 わずかに赤みがかった薄いクリーム色の背景と、濃いグレーの文字色をつかっている。 グローバルヘッダーのロゴっていうかサイトタイトルはSVGで手書きっぽい感じでおいた。 できるだけ画像を使用しないようにしたい。フォントは当初は游ゴシックを使っていたけど、 やっぱりちょっと堅いのでNotoSansを全面的につかった。日本語のWebフォントなんて重そうだけど、 まぁ一度読み込めばキャッシュされるし、読み込めないときはフォールバックで普通のゴシック体が使われるからいいでしょう。

スタイルシートは全てStylusで、Hugoで使われるHTMLテンプレートはjadeで書いた。 JekyllとかHexoみたいにブログエンジンから直接プリプロセッサを使うことはできないため、 Hugoからではなくgulpでさくっとビルドできるようにした。 Hugoではファイルの変更を監視し、それをトリガーにしてサイトのコンパイルを行うことができる。 これはgulpのwatchとも相性がいいのでデザインの更新やJsファイルの書き換えをしたいときは Hugoのwatchとgulpのwatchを同時に起動している。

いままでの写真投稿が鬼門だ。いままではtumblrが勝手に良い感じのレイアウトを作ってくれていた。 アスペクト比を崩さないように並べてくれるのだが、Hugoにはそんな機能はもちろんないし、 jQueryでも欲しいものは無かった。photoset-gridというのがあったが、 同じサイズの画像でないとちゃんと動かない。これではだめだ。 しかたないので自分でjQueryプラグインをつくった。 ブラウザやローディングのタイミングによっては崩れるバグがありそうなので、 それを修正してから近いうちに公開しようとおもう。

異なった画像サイズでもアスペクト比を維持して並べてくれるイカしたやつだ。

werckerで自動デプロイ

tumblrだと記事の保存と同時にインターネット上に公開される。とても楽なしくみだ。 でもHugoの場合はそのようなデプロイ作業はあくまでユーザーが行うこととなっている。 Hugoの守備範囲はあくまでも静的サイトの生成であって、公開とかプリプロセッシングとかそういうのは 守備範囲外なのだ。

それでは毎度毎度のサイト更新はどうしよう。まさかいちいちGithubPagesにgit subtreeなんてめんどくさい。 なのでCIツールを使う。werckerは最初からnpmやhugoが実行できるような環境を用意してくれているため、 短いスクリプトを書き、Web上で設定すれば完了だ。

box: wercker/nodejs
build:
  steps:
    - npm-install
    - script:
        name: Generate static files
        code: |
          ./node_modules/.bin/gulp build
    - arjen/[email protected]:
        version: 0.13
deploy:
  steps:
    - lukevivier/[email protected]:
        token: $GIT_TOKEN
        domain: xar.sh
        basedir: ./public

これからは$ git pushだけで公開ができる。GithubPagesを使っているので金も掛からないし、 tumblrとことなり自由な内容でサイトを作れる。 これからは全ての記事がMarkdownで管理され、またHugo以外のプラットフォームに移行する際もとても簡便だ。 tumblrにロックインされることもなく、自由で軽量な武器を手に入れた。 記事やデザインや設定に至るまで、全てがGit上で管理できることによりもたらされるポータビリティは計り知れない。 使い慣れたテキストエディタで日記くらい書きたいものだものね。 Wordpressの記事投稿画面なんか地獄だ。初心者にはとても使いやすそうだけど、私はもうそのレベルではない。

旧URLからのリダイレクト

Hugoで生成されるサイトのURLはできるだけtumblrに似せる。 tumblrの内部で使われていた記事IDのURLをそのまま使えるように、/post/謎の番号でアクセスできるようにする必要がある。 しかし、記事タイトルにアルファベットや数字が使われている場合はslugとして勝手に付加されてしまっているため、 Googleなどの検索エンジンにはslug有りのURLが登録されている。 このままでは検索エンジンからアクセスすると404になってしまうページがあるため、リダイレクトさせよう。 私はCloudflareのPagerulesをつかった。Pagerulesでは正規表現の一部が使えるのでslug有りでアクセスされた場合に、 slug無しのURLへPermanent redirectする。検索エンジンが正しいURLをクロールしてくれるまではこれでしのごう。

今後の記事作成フロー

Hugoでは新しい記事を生成を簡単に行うコマンドがある。その際ファイル名を指定しなきゃならないんだけど、 毎回英語のタイトルを考えるのも面倒だし、今までのtumblrにおける記事IDと統一感が無くなりそうだ。 細かいところなんだけど、一応全て数字で管理した方が便利は便利かと思って今後のURLは全てコマンド入力時のUnixtimeにした。

$ hugo new post/`date +%s`.md

とすれば、とりあえず重複の無いファイル名で新しい記事ができあがる。 このコマンドはどっかにエイリアスとして書いておけばいいかな。 Hugoにnewコマンドの挙動を変化させる設定とかあるのだろうか。あったらそっちを使いたい。

記事中で使う画像はflickrの埋め込みURLから使い、できるだけミニマルなリポジトリを維持すべきなのだけど、 tumblr時代にちょっとだけ手を染めてしまったphoto投稿がつらい。 もちろんHugoで生成されたサイト自体はGitの管理下に置かないが、全部の画像をflickrに上げてURLの置き換えを行うのはつらいので今はしない。 デカい画像と動画を配信しているページもあるけど、まぁ目をつぶろう。いつか整理しても良いけど、コスパ悪い感じだ。

おわりに

ポートフォリオくらいつくれとさんざん言われているのだけど、自分をアピールするのが苦手な性分であるため なかなか腰が上がらなかった。まだまだ細かいところに手を入れていきたいけど、ひとまずはこれでいいかしら。