杏z学習帳
Swiftを中心にFlutterやらUnityなどに手を出してます

ブログのジェネレーターををSwift製のPublishに移行した話(2020/09/21)

ブログのジェネレーターををSwift製のPublishに移行した話

急に思い立って以前からやろうと思っていた、ブログの静的サイトジェネレーターを Metalsmith から Pulish へ移行しました。

Publish

Swift製の静的サイトジェネレーターです。

Swift製っていうだけでそそりますね?(ググラビリティはわるいですけど 笑)

この記事の前までは Metalsmith っていうのを使って構築していたのですが、これの開発は随分前に止まっているように見えるのです。 なので、なにか他のものに移行したいのと思ってリサーチとかはしていたところ、Publish を見かけた感じでした。
とはいえ、リサーチしてた結果では Gatsby.js が良さそうで(知見の記事とかをみかけるし)迷ってはいたのですが、やっぱり疼くんですよね、アマノジャックが。
「そんなメジャーなのでやって本当にええんか?」と...(笑)
といういつもの後押しがあって Publish 採用です。(Metalsmith 採用した時もそんなノリだったような...)

移行する

セットアップなんかは README の Quick start の項を見たら問題ないと思うので触れずに、肝心のページ生成の部分がどんなもんなのかを。

Publish のページ生成は大きく6つのページ生成メソッドがあります。

これらです。タグ系はアイテムページでタグ指定しなければ使われることは無いはずです。
デフォルトで用意されているテーマではなく、自分でカスタマイズしようと思ったら、HTMLFactory プロトコルに準拠したものを作成して、上記のメソッドを実装していけばおkというわけです。

最もシンプルなブログ構成で行こうと思えばmakeIndexHTML と makeItemHTMLぐらいでをちゃんと実装したらよさそうな気もします。

記事自体はマークダウンで書いていく感じになります。

コード

超ざっくりとした流れは上の感じとして、実際のコードってどうなの?っていうのが気になると思うので、少しだけ紹介

struct BlogFactory<Site: Website>: HTMLFactory {
    func makeIndexHTML(for index: Index, context: PublishingContext<Site>) throws -> HTML {
        .HTML(
            .lang(context.site.language),
            .head(for: index, on: context.site, stylesheetPaths: ["stylesheetのパス"]), // headerタグをよしなに書いてくれる
            .body(
                .header(
                    .div(
                        .class("site-logo")
                    ),
                    .p(
                        .class("site-description")
                        .text(context.site.description)
                    )
                ),
                .div(
                    .class("wrapper"),
                    .article(
                        .p(
                            .text("ようこそ!!")
                        )
                    )
                )
                .footer(
                    .p(
                        .text("copyrightとか")
                    )
                )
            )
        )
    }
}

という書きっぷりです。
HTML を書いたことあったり、読んだことがある人であれば、特に迷うことなく読めるのではないでしょうか?
直接書いたほうがはやい!!とか思ったら、.raw() でもう一気に書いてもありかもしれません(笑)

リストなんかは、.forEach というものが用意されているので以下の様に書けます。

.ul(.forEach(context.allItems(
    sortedBy: \.date,
    order: .descending
)) { item in
    .li(
        .text(item.title)
    )
})

これぐらいが基本の書き方です。どうでしょう?やりたくなってきましたね??
自分が一応Swiftを第一言語としているのでそこまでハマることなく作業はできた気がします。

こんな感じで黙々とコードを書いて、無事に移行は完了しました。
どっちかというと、記事の移行が時間かかりました。もともと md で書いてて、メタデータも yaml と構成は全く一緒だったのですけれど、
ちょっと yaml の方を変更しないといけないということになって黙々とその作業を(笑)
(もしかしたらやらなくても良かったのでは説が終わったあとに浮上していましたが...😇)
リソース系(cssとか画像とか)は普通にコピペで済みましたね。

実際にローカルで確認したい場合は publish run を実行すると localhost で見られるようになります。

諦めたこととか課題とか

すべて万々歳なにも問題なくいったのかというそうでもなくて、諦めたこともあります。

ページングは諦めた

見てもらったら分かると思うのですが、トップページ > すべての記事を見る で遷移するとすべての記事が見られます(何を言っているんだ)
ページングとか何もなしで、すべての記事がリストでつらつらーっと表示されるはずです。
これは、Publish で ページング の実装をどうやるのかわからなかったからなんですよね。

困ったなと一瞬思ったのですが、でもよくよく考えると、ブログって記事リストを目Grepで読みたい記事を探すっていうことはほぼしない。大体はGoogleなりで検索して直接該当記事に飛ぶはず。
そこで気になればトップページに飛んで他にどんなの書いてるだろう?とか同タグのものをちょっと追ったりするぐらいならありますが、リストをいちいち全ページさかのぼって探すなどと...そんなオペレーションはほぼ無いなと思ったので、許容しました(笑)
(むしろページ内検索とかできて良いのでは!?などと)

HTMLタグのなかでマークダウン記法が書けない

記事内では基本的にマークダウン記法で書いているのですが、
稀に装飾をしたくて少し HTMLタグ を混ぜているところがあったりします。
そういう場合インライン要素みたいに一部なら問題ないのですが、ブロック要素を使った場合に問題が。

つらつら文章があってちょっとテイスト変えたいな。。

<div class="foo">
ここだけ少しテイスト違う見え方になるよ

### 見出し

文章文章

![画像](/images/bar.jpg)

</div>

という感じで書くと、Publish で使われているパーサーがうまいこと対応してくれず、思った通りの表示にはなりません。
のでブロック内ではマークダウン記法諦めて、HTMLを自前で書くということにしました。

それらしき PR が出ているのでマージされれば対応されそうな気もしますが、、結構放置されているんですよね。

引用の表示

引用で複数行のテキストが適切に改行されて表示されない問題。1行にまとめられてしまうのですよね。
他にも、マークダウン記法で引用は > を使って書き始めると思いますが、引用文章内に同記号があると正しく表示されなくなってしまいます。
なので、エスケープをする必要があるのかな?とか思って色々やってみたですが、結局できなかったですね。。
などと、引用周りは少し表示が怪しい感じがあります。
(もちろん自分がなにかトチっている可能性も大いにあります)

結局どうしたのかというと、1行にまとめられてしまう問題は、そもそも使用箇所が多くないし許容しました(笑)
> が文章内にあると表示が崩れるのは、文章内からそれを取り除きました(なくても意味がわかるので)
という対処療法的なことでうやむやにしています。

言っていることは少し違うのだけれど関連しそうな PR も一応ありました。

こちらもだいぶ時間は立っているますが...
Ink リポはあまり活発とは言い難いのかもしれません 🤔


ざっくり書き方と気になるとこを書いてみましたが、個人的にはわかりやすく進められたので満足です。
日本で Publish で実際にちゃんと運用している人ってそうそういないのでは?そう思うとなぞにテンションあがりますね!