新しいブログシステムを構築した
June 10, 2020
ブログやエッセイのような個人のテキストを溜めておく場所の構築について、長い間取り組む機会を伺うばかりでいたところから、ようやく既存のブログたちから移行しても良いかもというレベルのものが出来てきた。
スタティックサイトジェネレーションに関する技術、Jekyll にはじまり Octpress, Harp, Hugo, Gatsby, Nuxt, Next とブログシステムとして扱うのに都合の良いフレームワークを見るたびに、この技術で組んでしまえば...と構成を考え直すという頻度の高さに少し疲れて距離を置きながら、個人的に遊んでいる Elm で構築を進めることにした。
かつて blosxom の名前を cho45 さんから初めて聞かされた時(本人は聞き手たちが全く知らないことに驚いていた)はわからなかったが、自分のテキストをどう扱うかというのに向き合って SaaS なブログをあまりすすんで使いたがらない人の気持ちに少し追いつき始めたように思う。tDiary を更新しながらずっと使い続けている人もそうかもしれない。
ほとんどは Siteelm というとてもシンプルな Elm のためのスタティックサイトジェネレータに乗っかっている。
- Instagramなど特定サイトの画像を引き込む
- 外部URLを埋め込むカード表示
- Atomフィードの生成
といったあたりは、はてなブログから脱してくるのに最低限自分で準備をする必要があり、多くはそこに時間を要した。
特定サイトの画像やカードの埋め込み
Siteelm の Dynamic Module の機能を利用して [embed:https://iframely.com/]
と書くと上のカードが出たり、[instagram:imageId]
と書くことで Instagram の画像を読む img
タグになるようにした。
Embedly の長いユーザでもあった(WebPayの公式ブログのとき、Octoptressで使っていた)のだけど、 iframely の OSS 版の存在が「万一サービスが死んだら応急処置しやすそう」と、あまり強くはないが iframely を使う決め手になった。これも自前にしたいのだけど、データを控えたり、キャッシュを構えたりするのにスタティックではないサーバの構築あるいは別の外部のサービスが必要になるので当初の目的からは外した。
はてなブログからの記事の移行
便利 Go クライアントで Markdown として全記事を取り出せた。
https://hmsk.hatenablog.jp をまず移行しているが、追って https://hmsk.hatenablog.com も連れて来たい。
フィードの生成と GitHub Packages
RSS リーダーの全盛は過ぎたみたいだけど、今も各ブログをRSS経由で読みに来てくれている人が多かったので、フィードを吐くのは要件として持っていた。
Siteelm にはフィードを吐くための機能がなく、Elm としても JavaScript へトランスパイルする言語である性質上、HTM Lの上でごにょごにょするのには回りくどい対応が必要だった。
Siteelm 自体はトランスパイルされた Elm のコードを JSDOM の空間で実行し、最終的なHTMLを成果物として出力するようなつくりであるため、特定のセレクタの下に展開した XML を抜き出すような処理を加えることでフィードの生成を若干無理やり実現した。
siteelm.yaml
で feed
を指定すると
build:
dist_dir: ./dist
contents:
src_dir: ./src/pages
index: ./src/pages/index.md
feed: ./src/pages/feed.md
exclude:
- ./**/*.yaml
.html
の代わりに .xml
が生成され、feed
タグ以下全てが書き込まれる。
const parsed = parseFragment(ds.window.document.querySelector('feed')?.outerHTML || '')
return "<?xml version='1.0' encoding='UTF-8' ?>\n" + serializeToString(parsed)
あとは Preamble -> Static/Feed.elm という Siteelm の定義する流れに沿ってコンテンツを構築すれば良いように。
---
module: Static.Feed
entries:
preamblesIn: ./entries
---
Nothing to write here :P
Siteelm の Author がお忙しいのか、最近送った別のバグ修正のためのプルリクエストが相手にしてもらえないこと、フィードのための実装がその Author の想定するロードマップにあるかもわからないまま、こういう無理やりな実装で煩わせたり、マージされてリリースを待つみたいなサイクルも大変そうだったのでフォークして自分の意図するような形に作り変えていくことにした。
npmjs.org にて @hmsk/siteelm
として出すかと思ったら、個人アカウントである hmsk
をオーガニゼーション化しないといけないらしく、既存のモジュールたちはどうなってしまうのだ...と引き返して、ちょうど気になっていた GitHub Packages を使うことにした。
https://github.com/hmsk/siteelm/packages/261756 にパッケージを公開するように取り回した。フォークしたリポジトリの方の package.json
に設定を加え、Personal Access Token を準備してから npm publish
するだけですんなり公開できた。
"publishConfig": {
"registry":"https://npm.pkg.github.com/"
}
ブログのプロジェクトの方では .npmrc
にて @hmsk
を使いたい旨を明記するとすんなり。
registry=https://registry.npmjs.com/
@hmsk:registry=https://npm.pkg.github.com
ホスティングしている Netlify に出してみてから気づいたが、パブリックなリポジトリであろうと GitHub の認証を通す必要があったようで最終的には環境変数を引き込むこととなった。
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
registry=https://registry.npmjs.com/
@hmsk:registry=https://npm.pkg.github.com
ローカルとプロダクションでこういうところの差異が出るのも避けたくなって、Direnv でローカルの環境変数の世話もやるようにした。
Japonica
このブログのソースコードおよび記事のデータは全て
にある。いずれはブログシステム部分を分離して Siteelm のように簡単に Elm で静的サイトを構築できるような仕組みになったらいいかなと考えている。フォークした Siteelm がまだ大きく変更されていくようなら。
ちなみにこの記事は色んなマークアップに対するスタイルを調整するためのプレビューとして書かれた。