htmxで browser history API を活用する方法と a-blog cms 実装のポイント
htmx は標準で browser history API をサポートしており、属性に hx-push-url="true" を追加することで、これを簡単に利用できます。a-blog cms をバックエンドで使用する際の注意点をいくつか紹介します。
※(例)と書かれている部分は実際には動作しません。
hx-push-url 属性を設定して正しく動作する GET
<a>タグでの GETリクエストに対しては、htmx のドキュメントに従い、hx-get属性と hx-push-url属性を追加することを推奨します。
<a href="entry-1.html" hx-get="entry-1.html" hx-push-url="true">記事詳細</a>
hx-push-url 属性を設定しても正しく動作しない POST
POSTリクエストのケースでは、例えば a-blog cms でカスタムフィールド station を選択するための <select> を含むフォームを使用し、結果を表示するテンプレートとして include/htmx/result.html を指定する方法があります。
<form hx-post="" hx-push-url="true" hx-trigger="submit" hx-target="#search-result" hx-ext="ajax-header"> <select name="station"> <option value="Tokyo">Tokyo</option> <option value="Osaka">Osaka</option> <option value="Nagoya">Nagoya</option> </select> <input type="hidden" name="field[]" value="station"> <input type="hidden" name="tpl" value="include/htmx/result.html"> <input type="submit" name="ACMS_POST_2GET" value="検索" > </form> <div id="search-result">この部分に結果が表示されます</div>
a-blog cms の仕様として、<form> の POST 時 name="ACMS_POST_2GET" が送られてくると、検索条件( station = Nagoya )から URL を組み立て、その後リダイレクトされ GET に変換され、以下のような URL でアクセスした結果を取得できます。
https://example.com/htmx/result.html/field/station/Nagoya/
ここで問題が発生します。 上記の URL がブラウザに表示され履歴にも登録されますが、この URL にアクセスすると Ajax で追加される部分的な HTML になってしまいます。この検索結果で履歴に登録されて欲しい URLは、テンプレートファイル include/htmx/result.html のパスが無い以下の URL であって欲しいのです。
https://example.com/field/station/Nagoya/
hx-push-url 属性を設定しても正しく動作する POST 解決編
ここまでで a-blog cms POSTリクエスト後に URL を組み立てる ACMS_POST_2GET の処理が、htmx の hx-push-url と相性が悪い状況を解決する方法を考えてみました。
以下に示す JavaScriptコードを追加することで、hx-push-url 属性の動作を維持しつつ、希望する URL形式を browser history API に正しく渡すことができるようになります。
<script> addEventListener('htmx:beforeHistoryUpdate', function (event) { const proposedUrl = event.detail.history.path; const customUrl = proposedUrl.replace(/\/include\/htmx\/.*\.html/, ''); event.detail.history.path = customUrl; }); </script>
処理としては htmx で History を更新する前の path を取得し、/include/htmx/ 〜 .html 部分を削除するという処理を追加しています。
一般的に a-blog cms の部分的なファイルは include ディレクトリに整理して保存するというルールが定着していますので、htmx で読み込むテンプレートファイルは、その include ディレクトリ内に htmx を用意し、その htmx ディレクトリ内で管理というルールでテーマを構築というルールにする事で上記の JavaScript が有効的に動作させることができます。