JavaScript ライブラリ htmx と a-blog cms は相性が良さそうだ
htmx という JavaScript のライブラリが、2023 JavaScript Rising Stars : Front-end Frameworks で 2位 になっているが、日本ではあまり聞かない。私自身も最近知ったばかりだが面白そうなので、いろいろ実験を始めたところです。
他にも、調べてみると 【GitHub Accelerator】GitHubが選んだ、将来有望なプロジェクト20選 というのも見つかり、その中にも htmx が選ばれているようです。
- 2023-04-12 : GitHub Accelerator: our first cohort and what’s next
世界的に見れば、結構話題になっているという事になります。
そんな中で、日本国内ではどんな感じかを調べてみるときのリンクを以下に。
- Qiita : htmx 20件
- Zenn : htmx 9件
- X : #htmx lang:ja 日々少しある
- YouTube : htmx 日本語では数件
- Google : htmx + 日本語を検索
海外と比べると、ほとんど無いと言ってもいいくらいな状況であることがわかります。
Qiita や Zenn の記事を読みつつ、何で日本では流行ってないんだろ?って考えてみると、今の日本国内ではフロントエンドのフレームワーク的なものを使おうと思う人たちは、やっぱり React や Vue のような JavaScript をしっかり書くような人が多いのではないだろうか。
そんな中で htmx は、JavaScript で実装するものではなく、HTML のテンプレートを書きつつ、必要なところだけサーバーサイドから欲しい HTML を返してくれる必要があるので、普段使ってる JSON を返してくれる ヘッドレスCMS では欲しいデータを返してくれないということになる。
そうなると、そこに学習コストをかけようということになってないのかもしれない。私の勝手な考えではありますが...
私自身が、JavaScript をバリバリ書く人ではないので、書かないでもいい!って言われると、私と似た属性の人たちに紹介したくなるので、少し初歩的なところも書いておきます。
htmx とは
htmx は、ウェブページにインタラクティブな機能を簡単に追加するために設計された、HTMLを拡張するJavaScriptライブラリです。このライブラリを使用すると、サーバーと非同期に通信し、ページの一部を更新することができます。これにより、ページ全体を再読み込みすることなく、ユーザーインターフェイスを動的に更新することが可能になります。
htmx は、HTMLの属性を使用して動作します。これにより、JavaScriptをほとんどまたは全く書かずに、多くの一般的なウェブ開発タスクを実行できます。例えば、ある要素をクリックしたときに特定のURLからコンテンツを取得してその要素内に表示する、といった動作を簡単に設定できます。
htmx は、モダンなウェブ開発のアプローチの一つとして注目され、Ajax、WebSocket、サーバー送信イベント(SSE)などの技術をより簡単に活用できるようにすることを目指しています。
htmx の主な特徴
以下のような主な特徴を持っています。
簡単なインストールと設定
単一のJavaScriptファイルを HTML に追加するだけで利用開始できます。
<script src="https://unpkg.com/[email protected]"></script>
HTMLを拡張する
特別な hx-* 属性をHTMLタグに追加することで、非同期通信 ( ajax ) や DOM の更新を行うことができます。
属性 | 説明 |
---|---|
hx-get | 指定されたURLからデータを非同期で取得し、現在の要素を更新します。 |
hx-post | 指定されたURLに対してPOSTリクエストを非同期で行い、現在の要素を更新します。 |
hx-put | 指定されたURLに対してPUTリクエストを非同期で行い、現在の要素を更新します。 |
hx-patch | 指定されたURLに対してPATCHリクエストを非同期で行い、現在の要素を更新します。 |
hx-delete | 指定されたURLに対してDELETEリクエストを非同期で行い、現在の要素を更新します。 |
簡潔さとアクセシビリティ
インタラクティブな Webアプリケーションを作成するために、JavaScript のコードをほとんどまたは全く書く必要がありません。
<button hx-post="/clicked" hx-trigger="click" hx-target="#parent-div" hx-swap="outerHTML" > Click Me! </button>
上記は、公式サイトにあるサンプルコードでは、(Click Me!)ボタンをクリックすると、https://example.com/clicked に POST して、取得した HTML を id="parent-div" と置き換える処理が実行されます。
開発者は複雑なJavaScriptやフレームワークに頼ることなく、HTMLの拡張を通じてインタラクティブなウェブアプリケーションを構築できます。これにより、コードベースが簡潔に保たれ、メンテナンスや理解が容易になります。
低い学習曲線
HTML属性を利用することで機能を実現します。そのため、HTMLの基本的な知識があれば、追加のプログラミング言語やフレームワークを学ぶことなく、すぐに使用を開始できます。
サーバー中心のインタラクション設計
サーバーサイドのロジックを活用して、クライアントサイドのインタラクティビティを向上させます。これにより、サーバーとクライアント間の連携が強化され、開発プロセスが合理化されます。
この htmx の通信をするサーバー側の処理を簡単にできたら、さらに便利に htmx が使えそうではないですか。
スムーズな統合性
既存のウェブアプリケーションに簡単に統合でき、大規模な書き換えを必要としません。これにより、従来のウェブサイトを段階的にアップグレードすることが可能になります。
パフォーマンスと効率
必要な部分のみを更新することで、全体のページリロードを避けます。これは、帯域幅の使用を削減し、アプリケーションのパフォーマンスを向上させます。
幅広い互換性
現在、リリースされている htmx 1.x では IE11 もサポートしているようです。もちろん現代のブラウザであれば問題なく動作します。 2.0.0-alpha1 リリース され、IE のサポートを終了したそうです。(もう IE は対応しないでいいですよね)
htmx と a-blog cms の相性が良さそうな理由
htmx のことを調べて、ここに辿り着いた人は a-blog cms なんて知らないかもしれないので、少しだけ説明をしておきます。
a-blog cms とは
PHP + MySQL で動作する国産の ローコードCMS で、基本的には HTMLファイルとしてテンプレートを作り、PHP や JavaScript など難しい事は書くことなくウェブサイトを作ることができる CMS(コンテンツ・マネージメント・システム)です。
a-blog cms には htmx に似た Ajax 機能が標準搭載
a-blog cms には post include 機能 という名称で10年前から htmx のような ajax 機能を用意しています。よく利用される記述をサンプルコードを紹介します。
<form action="" method="POST" class="js-post_include-ready"> <input type="hidden" name="tpl" value="include/sample.html"> <input type="hidden" name="ACMS_POST_2GET"> </form>
class="js-post_include-ready" がある form では、ページが表示された後に include/sample.html を読み込みます。また、sample.html には以下のようなコードが書かれているとします。
<!-- BEGIN_MODULE Entry_List --> <ul> <!-- BEGIN entry:loop --> <li><a href="{url}">{title}</a></li> <!-- END entry:loop --> </ul> <!-- END_MODULE Entry_List -->
これで、何件かのリストが表示されることになります。 このように、a-blog cms では標準的な機能として、Ajax でリクエストがあった情報を部分的に HTML で返すことができる機能を持っています。
これ htmx でやってることと同じです。もちろん、これまで通り純正の post include で作るということでもできますが、htmx の方が機能が豊富なので、置き換えることも可能ではないだろうかと考えています。
実際の post include の動作デモ
以下の青いボタンをクリックすると、このブログの新着記事を5件 Ajax で読み込み、その読み込まれたコードにも続きを読むボタンがありますので、繰り返し読み込むことができるようになっています。
a-blog cms の post include は、標準的に消して、出てくるアニメーションがついているので、下の htmx のデモと違うもので動いているのが分かりやすいと思います。
ボタンのコード
class="js-post_include" がある <form> タグは画面を遷移せずに、Ajax でコンテンツを読み込みます。
<form action="https://kazumich.com/include/sample.html" method="POST" class="js-post_include"> <p class="acms-text-center"><input type="submit" name="button" value="デモ(ajaxでコンテンツを読み込みます)" class="acms-btn acms-btn-danger acms-btn-large"></p> </form>
読み込まれる sample.html のコード
上半分が記事の一覧を読み込む部分で、下半分が続きを読むためのボタンのためのコードになります。
<!-- BEGIN_MODULE Entry_Summary id="post-include-sample" --> <div class="acms-margin-bottom-medium"> <ul class="acms-list-group"><!-- BEGIN unit:loop --><!-- BEGIN entry:loop --> <li class="acms-list-group-item"> <a href="{url}" class="acms-list-group-title-link">{title}</a> </li><!-- END entry:loop --><!-- END unit:loop --> </ul> <!-- BEGIN pager:veil --> <!-- BEGIN forwardLink --> <form action="" method="POST" class="js-post_include"> <input type="hidden" name="tpl" value="include/sample.html"> <input type="hidden" name="page" value="{forwardPage}"> <p class="acms-text-center"> <input type="submit" name="ACMS_POST_2GET" value="次の{forwardNum}件へ" class="acms-btn acms-btn-danger acms-btn-large"></p> </form><!-- END forwardLink --> <!-- END pager:veil --> </div> <!-- END_MODULE Entry_Summary -->
post include を htmx に置き換えてみる
やる事は簡単で <form> タグ部分の属性を書き換えます。見やすく属性毎に改行していますが、もちろん 1行でも大丈夫です。
ボタンのコード
こちらは https://kazumich.com/include/sample-htmx.html を GET で読み込むように設定してみました。
<form hx-get="https://kazumich.com/include/sample-htmx.html" hx-ext="ajax-header" hx-trigger="click" hx-target="this" hx-swap="outerHTML" class="acms-text-center" > <input type="submit" name="button" value="デモ( htmxでコンテンツを読み込みます)" class="acms-btn acms-btn-primary acms-btn-large"> </form>
読み込まれる sample.html-htmx のコード
こちらは、何ページ目という情報を POST で渡すカタチで書いています。
<!-- BEGIN_MODULE Entry_Summary id="post-include-sample" --> <div class="acms-margin-bottom-medium"> <ul class="acms-list-group"><!-- BEGIN unit:loop --><!-- BEGIN entry:loop --> <li class="acms-list-group-item"> <a href="{url}" class="acms-list-group-title-link">{title}</a> </li><!-- END entry:loop --><!-- END unit:loop --> </ul> <!-- BEGIN pager:veil --> <!-- BEGIN forwardLink --> <form hx-post="" hx-ext="ajax-header" hx-trigger="click" hx-target="this" hx-swap="outerHTML" class="acms-text-center" > <input type="hidden" name="tpl" value="include/sample-htmx.html"> <input type="hidden" name="page" value="{forwardPage}"> <p class="acms-text-center"> <input type="submit" name="ACMS_POST_2GET" value="次の{forwardNum}件へ" class="acms-btn acms-btn-primary acms-btn-large"></p> </form><!-- END forwardLink --> <!-- END pager:veil --> </div> <!-- END_MODULE Entry_Summary -->
head タグに追加する htmx のライブラリを読み込むコード
a-blog cms のテンプレートの中で、htmx を呼ぶためには、hx-ext="ajax-header" を追加する必要があります。そして、これを利用するためには、<head> タグ内に以下のように htmx のライブラリとあわせて ajax-header.js も読み込みます。
<script src="https://unpkg.com/[email protected]"></script> <script src="https://unpkg.com/htmx.org/dist/ext/ajax-header.js"></script>
最後に
htmx で渡される HTML 自体をテンプレートとして表示部分を記述し、POSTするだけで a-blog cms は結果を HTML として返してくれます。上記のサンプルコードをご覧になれば、htmx が簡単に Ajax 部分を処理してくれているのと同様に、a-blog cms が必要な HTML を整形してくれることがわかります。
必要な部分だけ JSON で返してくれる ヘッドレスCMS と違い、必要な部分だけ HTML を返してくれる機能を a-blog cms は持っているのです。このように、a-blog cms と htmx の相性はとってもいいのではないかと考えています。
ローカル環境での利用や、個人が非商用で利用する際には無料で、費用はかかりません。htmx の学習の環境として a-blog cms 使ってみませんか?