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 の処理が、htmxhx-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 が有効的に動作させることができます。

同じタグ付けがされている記事