コンテンツの読み込みに時間がかかっています

a-blog cms 3.2 で htmx を標準サポートすることになりました

まだ正式版 Ver. 3.2 リリース前ですが、今日は「ハイパーメディアシステム──htmxとRESTによるシンプルで軽やかなウェブ開発」の発売日という事もあるので htmx の記事を書いてみる事にしました。


a-blog cms Ver. 3.2 で htmx を標準サポートする事になりました。


Ver. 3.1 までの htmx 対応について

Ver. 3.1 までは、以下のような JavaScript を <head> 内に事前に記述しておく必要がありました。htmx を活用する際に、どのような準備が必要だったのか、今後の参考のためにも記録しておきます。

htmx 本体の読み込み

htmx を実行するためには、ライブラリ本体が必要です。テスト時は CDN からの読み込みでも問題ありませんが、本番運用ではセキュリティや可用性の観点から自社サーバーへ設置することを推奨します。

<script src="/themes/htmx@blog/js/htmx.mim.js?date=20241228155737"></script>

htmx のカスタム設定

historyCacheSize = -1 : htmx は通常、ブラウザの「戻る・進む」操作時にキャッシュしたページ断片を再利用しますが、CMSの状態や認証等でキャッシュが問題になることが多く、必ず最新の内容を取得するためにキャッシュを無効化しています。

refreshOnHistoryMiss = true : キャッシュに無い場合は自動的にページを再取得します。

<script>
  htmx.config.historyCacheSize = -1;
  htmx.config.refreshOnHistoryMiss = true;
</script>

ヒストリーAPI用URL整形

ヒストリーAPI に記録する URL に /tpl を含むものを記録しないようにするために、/include/htmx/ が含まれる際には include/htmx/filename.html を削除するような処理を追加しています。

<script>
  addEventListener('htmx:beforeHistoryUpdate', function (event) {
    const proposedUrl = event.detail.history.path;
    let customUrl = proposedUrl;
    if (proposedUrl.includes('/include/htmx/')) {
        customUrl = proposedUrl.replace(/\/include\/htmx\/.*\.html/, '');
    }
    event.detail.history.path = customUrl;
  });
</script>

CSRFトークンの自動付与

a-blog cms では <form> のタグでは自動で CSRFトークンのタグが自動挿入されますので hx-post には必要ないのですが、hx-get の際にも CSRFトークンを利用可能にするための設定になります。

<script>
  document.addEventListener("htmx:configRequest", function(event) {
      const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
      event.detail.headers['X-CSRF-Token'] = csrfToken;
  });
</script>

htmx 実行後の acms.js 再実行

htmx を利用し Ajax でコンテンツを読み込んできた部分の HTML で a-blog cms で用意している JavaScript ( acms.js ) が必要な時に再度実行させます。

<script>
  addEventListener('htmx:afterSwap', function (event) {
    ACMS.Dispatch(event.target);
  });
</script>

Ver. 3.2 以降の htmx 対応について

上記の事前準備的な設定が必要なくなりました。

hx-gethx-post などの属性を HTML に記述するだけで、自動的に必要な環境が準備されます。

従来は class="js-post_include" のような記述で Ajax コンテンツの読み込みを実現していましたが、今後は hx-post への置き換えにより、より柔軟かつ高度な制御が可能になります。さらに hx-get を利用することで、<a> タグでも Ajax 読み込みが可能となります。

hx-post & hx-push-url の利用の際(ヒストリーAPI 用 URL 整形)

hx-get の場合は hx-push-url="{url}" を設定することで問題ありませんが、hx-post の場合はテンプレートで事前に ヒストリー API に登録する URL を決めることができません。そこで、必要なタイミングでのみ ヒストリー API 用 URL 整形処理を実行できるようにしています。

hx-post & hx-push-url を利用する場合は、テンプレートファイル内の任意の場所に data-acms-hx-push-url 属性を追加してください。値は不要です。

<article class="entry" data-acms-hx-push-url>
 ...
</article>

htmx の実装について

基本的な属性の設定

<a href="{url}"> を以下のように hx-属性 を追加します。

htmx のポイントは、hx-get の URL を「取得したいコンテンツのパス(通常は /tpl/ 配下)」に指定する点です。

一般的には hx-push-url="true" としますが、true の場合は tpl を含む URL が履歴に残ってしまうため、hx-push-url="{url}" のように本来の URL を明示的に指定します。

<a href="{url}" 
  hx-get="{url}/tpl/include/entry-body.html" 
  hx-push-url="{url}"
  hx-swap="innerHTML"
  hx-target="#main-contents">

テンプレートの設定

まず _entry.html と entry-body.html の記述方法を理解できれば、他のテンプレートも同様に記述できます。

_entry.html

全体は割愛しますが、entry-body.html をインクルードする際は変数 multi_swap : off に設定します。

@include("/include/entry-body.html" , {"multi_swap" : "off"})

entry-body.html

通常は Entry_Body のみを記述しますが、このテンプレートでは「トピックパス」やタイトルタグの書き換えも同時に行えるように設計します。

<!-- BEGIN_IF [{{multi_swap}}/neq/off] --> の指定により、_entry.html からの読み込み時には非表示にし、htmx での呼び出し時のみ表示させるよう分岐します。

また、hx-swap-oob="true" の指定により、id="topicpath" のエリアを置き換えることができます。

<!-- BEGIN_MODULE Entry_Body id="entry_body" -->

(内容は省略)

<!-- END_MODULE Entry_Body -->

<!-- BEGIN_IF [{{multi_swap}}/neq/off] -->
 <!-- BEGIN_MODULE Topicpath id="topicpath" hx-swap-oob="true" -->

 (内容は省略)

 <!-- END_MODULE Topicpath -->

 <!-- BEGIN_MODULE Ogp -->
 <title>{title}</title>
 <!-- END_MODULE Ogp -->

<!-- END_IF -->

最後に

X.com で #ablogcms を検索してみたところ、嬉しい POST を発見したのでご紹介します。この最初に紹介した本を読んだ方が、「a-blog cms の開発者向けドキュメントを読んでいるような気分になってきた」と感想を書いてくれていました。

a-blog cms をバックエンドに使うことで、バックエンド側を何も書かないで htmx をサクサク利用できるようになります。 ぜひ、ablogcms.io でお試しを!



関連記事

この記事のハッシュタグ から関連する記事を表示しています。

a-blog cms と htmx で作る SPA(Single Page Application) なブログテーマの実装方法

JavaScript ライブラリ htmx と a-blog cms は相性が良さそうだ

生成AIポッドキャスト時代なので a-blog cms の mp3対応を考えてみる

NotebookLMの音声概要が日本語対応! a-blog cms のポッドキャストを作ってみた

a-blog cms と View Transitions API で作るページ遷移のアニメーションの実装について

Entry_Summaryループ内クラス設定を運営者でも触れるようにする