続・ブログをはてなブログからHugo+Cloudflare Pages(+R2)に移行しました
Page content
この日記の続編。残課題とか、その辺について。
残課題対応
- SSL証明書のエラー云々と言っていた件は、SSL証明書が原因ではなかった。移行のミスで、画像の参照先URLのスキームがhttpsではなくhttpになっていて、httpsのページからhttpで画像を見に行ってることが原因だった。要するにただのアホ。スマホのChromeからだと証明書の部分に警告が出ていたのでてっきり証明書の問題だと勘違いしてしまっていた。注目すべきは 「このサイトで目にする画像は、悪意あるユーザーによって差し替えられたものである可能性があります。」 という部分だった。(ちょっとわかりづらくない??この表示)
というわけで再度、全501記事の画像参照先URLをhttpsに移行しなおし。501記事一括Commit。重かったぜ。イエア。 - カテゴリやタグに件数集計したい件は、
config.toml
の設定変更だけで終わった。[Params.widgets]
内のcategories_counter
およびtags_counter
をそれぞれtrue
にするだけで表示される。完了。。 - 年月ごとの集計をしたかった件。どうもArchiveというTaxonomyを別に用意して、それを使うやり方が一般的なようだ。こちらとかで紹介されている。ただ、移行時点ではここを意識してなかったので、
archive:
は付いていなかった。というわけで、しょうがないので移行後に再度全部つけた。(簡単なNode.jsのツールを組んで実行。2秒くらいで終わったw)幸いdate:
に記事の日時は出力されてるので、それを使ってarchive:
の値を生成して再出力した。ここまでが第一段階。 - 年月ごとの集計をしたかった件の続編。
archive
の値をもとに記事数集計してサイドバーに出すwidgetをつくる。基本的にはMainrodに備わっているcategoriesとかのpartialのコードをパクって新たにwidget用のhtmlファイルを作成した。ハマったのが以下の辺り。T "categories_title"
というコードがなんだかよくわからなかった。config.toml
に見当たらなくて、どこで設定するんだろうと思ってたら、i18n
ディレクトリ配下にあった。へー。後で調べてみたら確かにT
というのはTranslate
のAliasだった。なるほど。- Hugoのテンプレートの書き方がわからん。例えば、文字列の長さとるのにも一苦労だった。もっといいやり方がありそうだが、
$name | strings.Count ""
とか書いてとりあえず乗り切った。どうもstring.length
みたいないい感じのメソッドはなく、このstrings.Count
も、指定された文字が文字列内にいくつあるかを検索するメソッドらしくて、空文字を渡すことで文字数をカウントするという、なんとも切ないやり方だ。絶対なんか間違ってる。。気がする。その他、if
による条件分岐、range
によるループなど、書き方が独特で分からないことが多い。archives:
にはYYYYとYYYYMMで2種類の情報を付与してるので、2014年以降のarchives
をリストで出すと結構な長さになり、あんまり見栄えが良くない。はてなブログのときみたいに、初期表示はYYYYだけにして、クリックしたら配下の年月YYYYMMが開閉する、という作りがいいんだが、このHugoテンプレートの使い方がよくわからない絡みで、うまい具合に実装できなかった。というわけでとりあえず今はwidgetに出力するのはYYYYだけにしている。(上に書いた文字列長のチェックを使ってYYYYMMを省いている)ここはもう少しなんとかしたい部分なので、継続的に対応していくつもり。 - これの関連で、現在は2014~2024までが昇順で並んでいる形だが、これを降順2024~2014に変更したい。はてなブログがそうだったし、記事も降順で出てくるので、そっちの方が感覚に合っている。が、
archives
をソートする方法がわからない。。Alphabetical.Reverse
とかすればいいんじゃないかと思ってたんだが、これ書いたら何故かarchives
が全く見えなくなってしまった。なんでやねん。まあ多分なんか使い方が間違ってるんだろう。ここも継続して確認していく。
- Pagefindで独自の検索機能を付けたいという件。ほぼほぼこちらの記事に書いてある内容に沿って実施。結論、「比較的」簡単にできた。いくつか対応のポイントはあって、以下の辺り。
- Mainroadには一応Google検索用のWidgetが備わっているので、枠だけそれをパクって中身だけPagefindのGetting StartedのUIに書き換えた別widgetを用意して、
config.toml
のsearchのwidgetをそっちに変更した。ちなみに以下のような感じ。ほぼGetting Startedの内容のまま。大外のdiv
タグだけMainroad。<div class="widget-search widget"> <link href="/pagefind/pagefind-ui.css" rel="stylesheet"> <script src="/pagefind/pagefind-ui.js"></script> <div id="search"></div> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({ element: "#search", showSubResults: true }); }); </script> </div>
- この方のブログに沿って
pagefind_extended
を利用。ただしnpx pagefind_extended@latest
は動作しない。しょうがないのでリリースページから最新版のprecompile版をダウンロードしてきて解凍。hugo
のあとこの方と同じく./pagefind_extended --site public --glob="{posts}/**/*.html" --output-path="static/pagefind"
を実行。約10秒ほどで完了した。 - 解凍後の
pagefind_extended
は200MBを超えており、無邪気にgit push
するとGithubに怒られる。はい、怒られたやつです。。なのでリポジトリにはのせられない。かといって.tar.gz
あげるのもなんかちょっといただけない。というわけで、Cloudflare Pagesのビルドで頑張ってもらう事にした。Cloudflare Pagesのビルド環境はUbuntuベースのコンテナらしいんだが、wget
とかその辺ちゃんと入ってるのか心配だったか、とりあえずやってみたら動いた。ので、OKとする。以下のようなビルド用のshellを用意し、#!/bin/sh # build hugo echo "run hugo" hugo # download pagefind_exteded echo "download pagefind_extended from:${PAGEFIND_EXTENDED_URL}" wget ${PAGEFIND_EXTENDED_URL} gzip -d *.gz tar -xf *.tar # run pagefind_extended echo "run pagefind_extended" ./pagefind_extended --site public --glob="{posts}/**/*.html" --output-path="static/pagefind" exit 0
PAGEFIND_EXTENDED_URL
という名前で最新のリリースURLを指定して、Build Configurationでビルドのコマンドをsh custom-build.sh
のようにすればいい。普通に全部動いた。ただ、ビルド環境の詳細が不明なため(あまり調べられてもいないが…)、ある日突然wget
とか消えましたみたいなこともあるかもしれないので、ここは注意が必要な気もしている。少なくとも2024年1月26日現在は動くことを確認済。- とりあえず字ブログ内検索は実装できたんだが、Mainroadの名残で、検索結果がサイドバーの大きさでしか表示されないのが、若干いけてない気もしている。ここはそのうち直すかもしれない。
- Mainroadには一応Google検索用のWidgetが備わっているので、枠だけそれをパクって中身だけPagefindのGetting StartedのUIに書き換えた別widgetを用意して、
- 新規記事が出たときにTwitterに投稿したい要件。の手始めとしてまずRSSを確認。Mainroadのデフォルトだと
rssLimit
が存在しないせいか、作成された/index.xml
が見た感じ全部の記事がぶわーっと連なって出てきており、これが原因なのかブラウザで表示したりSlackのRSSフィードで読み込ませるとエラー起こした。とりあえずrssLimit=20
くらいにして生成したところエラー消えたので、一旦これで様子見る。なんらか記事を投稿しないとRSSの更新も確認できないが、とりあえずIFTTTのRSS Trigger Appletを仕掛けた。行き先はWebhookでLambda(+関数URL)。一旦これで動作確認してから細かいことを考える。Lambdaに向けてぶっ放つのは、Twitter投稿に必要なOAuth TokenがDynamoDBにあるから。AWSに乗せるのが一番わかりやすい。ついでに各地へのping通知もヤッちまうつもりだが、それは大した話じゃないので追々考える。とりあえずどういうデータが回ってくるのか一通りみてからだ。そもそもIFTTTが動かない気もしなくもないのでその辺も踏まえて検証が先決だ。
残課題とは別に実施した対応
- Twitter上でOGP画像が表示されていないことに気づいたので、修正。Mainroadは
/layout/_default/baseof.html
に{{ template "_internal/opengraph.html" . }}
とかのHugoでOGPを使うためのコードは既に記述されてるので、config.toml
でopengraph = true
とか設定してれば基本的にはそれでOK。画像が出ない件はまた別で、どうもconfig.toml
にimages = ["/img/xxx.png"]
を記述すればいいらしい。こちらのブログの記事が参考になった。画像は/static/
配下からの相対パス。 - Custom CSSの読み込みエラーが出ていたので、旧ブログ用に使ってたスタイルシート群を独立させて、Custom CSSとして配置してエラーを解消させた。ただ、よく考えたら
config.toml
のその行コメントアウトするだけでも良かったな。。まあ別にいいけど。 - もはやあんまり意味があるようにも思ってないんだが、一応はてなブログ時代に登録していたブログコミュニティへのリンクも追加した。超簡素なwidget用意してケツにくっつけた。だけ。スタイルの当たり方があまりにもアレなのでここはちょっと見直すかもしれない。ただ自分の中で優先度は低い。
他にやりたいこと
- いわゆるステージング環境的なやつがほしい。↑で書いたRSSの更新確認もそうだが、本番以外に何かもう一つ環境があると、やはり色々やりやすい気がする。Preview Deploymentsというのをうまく使えばできそうな気もするんだよな。この場合だけ実行コマンドを
hugo server -D
に設定すればよくて、かつそこにカスタムドメイン割り当ててCloudflareで我が家以外のアクセス拒否ればいいわけで、なんかできそうではある。まぁローカルでhugo server -D
するのもそんなに遅くはないのでそんなに優先度は高くないんだが、時間があったらやってみたい。 - Deploy Hookを使うと、「毎日0時に更新」とかいう機能も作れそうだな。と思った。これを構築すれば、未来日時の日記を裏で書いておいて(
draft: false
にしておく必要はある)、git push
さえしておけば、日を超えた瞬間の予約投稿みたいなことができなくはない。IFTTTでも軽いCronみたいなことはできたはずだから、スケジュールジョブ的にDeploy HookのエンドポイントにWebhookでリクエスト投げるのは、できなくはなさそう。まぁでも外側の仕組みを増やすと管理が面倒くさくなりそうだしな~どうしようかな~という気持ち。ここはエンジニア的好奇心によるところが強い。そのうちやる、かも。
それ以外に気付いたこと・やったこと
hugo
コマンドだけを単発で放つとビルドだけを実行してサーバーを起動しない、ということができる。pagefind
を実行するときに知った。へー。ただ、(知らないだけかもしれないけど)逆に「(ビルド済の資産使って)サーバー だけ 起動する」ってのが出来ない気がする。hugo server
ってビルドも一緒にやってるよね??そうなると、ビルド「だけ」を行う目的って何?という気はしなくもない。pagefind
みたいに、ビルド後の生成物をサーバー起動するまでの間に拝借する必要があるやつは、まぁわからんでもないが、Hugo本体的には必要とする場面あるのかなあ。という疑問はある。まあそんなに興味もないんだが。他のプラットフォームに移行するとき用とか??- Github ActionsのEnvironment Variableに「Secrets」のほかに「Variables」というのがあるのに気付いた。これ昔はSectretsだけじゃなかったっけ??知らずに最初Variablesの方触っちゃったけど、VariablesのほうはSecretsとは違って値が丸見えになるので、Secretsに比べてわかりやすい一方、セキュリティ的には若干抵抗も感じる。AWSのアクセスキーとかは載せる気にはなれないなあ。。昔作った、Github ActionsでLambdaにデプロイするワークフローは、Secretsを使ってるので、今回(RSS更新を受けて起動するLambda関数のリポジトリ)にも、Secretsを使う形で実装したので、Variablesを使う機会はなかったし、そういう意味では今後も使う場面がなさそうだが。どういう使い分けする想定で用意されてるのか少し気にはなる。もっと単純なビルドやCIの設定用かなあ?
- はてなブログProを解約した。といっても1年契約だったので6月までプランは継続するんだが。また、その関連で、はてなブログのping送信で使っていたIFTTTのアプレットを全部Archiveした。気付いたときにやっておかないとこういうのは絶対忘れるものだ。。あとはてなブログで「移行したのでもう更新しません」という最後の記事の投稿。この数日で、もうほぼ完全にはてなブログからは手を引いた。さらばはてなブログ。