最近htmxが話題になっているようなので、とりあえず触ってみました。
htmxホームページには、
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML">
Click Me
</button>
これは
ユーザーがこのボタンをクリックしたら、/clickedにAJAXリクエストを発行し、ボタン全体をHTMLレスポンスに置き換える。
と解説されています。HTMLタグの属性を拡張し、サーバーへのリクエスト等が簡単に書けるJavaScriptライブラリーです。
ドキュメントを見ても、通常のJavaScriptの構文ほぼ出てきません❗ HTMLと同じように宣言的に書けます❗
Bing Image Creatorが生成した画像を使っています
Ruby on Railsでhtmxを使ってみた
いつものジャンケンアプリをhtmxを作って行こうと思います。
Ruby on Railsのみ
バックエンドを含め、まずはRuby on Railsで基本機能を作ってみましょう
app/controllers/jyankens_controller.rb
コントローラーは以下のようになります、htmx用のメソッドの説明は後で行います。
- ① データベースのjyankensテーブルから対戦記録を取得し表示します
- ② ジャンケンのボタンを押したさいには、createアクションが実行されます
- ③ 次の事を考えジャンケンの処理をjyanekn_ponメソッドに書きました
- コンピューターの手は乱数で発生
- 勝敗を計算
- jyankensテーブルに結果を追加
class JyankensController < ApplicationController
def index # ← ①
@jyankens = Jyanken.order(created_at: :desc).all
end
def list # ← ⑩
index
render partial: 'list'
end
def htmx # ← ⑪
end
def create # ← ②
jyanekn_pon
redirect_to jyankens_url
end
def pon # ← ⑫
jyanekn_pon
redirect_to list_jyankens_url
end
private
def jyanekn_pon # ← ③
@jyanken = Jyanken.new(jyanken_params)
@jyanken.computer = rand(3)
@jyanken.judgment = (@jyanken.computer - @jyanken.human) % 3
@jyanken.save
end
def jyanken_params
params.require(:jyanken).permit(:human)
end
end
app/views/jyankens/index.html.erb
- indexページに対戦記録と、ジャンケンボタンを置きました
- 対戦記録表示は_listページに切り出しました
<p style="color: green"><%= notice %></p>
<h1>ジャンケン</h1>
<%= button_to "グー", jyankens_path(jyanken: {human: 0}) %>
<%= button_to "チョキ", jyankens_path(jyanken: {human: 1}) %>
<%= button_to "パー", jyankens_path(jyanken: {human: 2}) %>
<%= render "list" %>
app/views/jyankens/_list.html.erb
- 対戦記録の表示
<table>
<thead>
<tr>
<th>人間</th>
<th>コンピューター</th>
<th>勝敗</th>
</tr>
</thead>
<tbody>
<% @jyankens.each do |jyanken| %>
<tr>
<td><%= te_s(jyanken.human) %></td>
<td><%= te_s(jyanken.computer) %></td>
<td><%= judge_s(jyanken.judgment) %></td>
</tr>
<% end %>
</tbody>
</table>
app/helpers/jyankens_helper.rb
- ジャンケンの手や勝敗の文字列表示ヘルパー
module JyankensHelper
def te_s(te)
["グー", "チョキ", "パー"][te]
end
def judge_s(juge)
["引き分け", "勝ち", "負け"][juge]
end
end
htmx
いよいよhtmxですが、その前にhtmxから呼び出されるアクションを作っておきます。
- config/routes.rb
Rails.application.routes.draw do
resources :jyankens do
get 'htmx', on: :collection
get 'list', on: :collection
post 'pon', on: :collection
end
end
さきほどは説明しなかったコントローラーの説明
- ⑩ 対戦記録の部分のみ返すlistアクション
- ⑪ htmx用ページの表示アクション
- ⑫ ジャンケン対戦アクション
- 対戦データの作成後は、listアクションにリダイレクトされ実行されます
app/views/jyankens/htmx.html.erb
いよいよhtmxです😃
一見して気がつくように、JavaScript言語は書かれていません(もちろんhtmxはJavaScriptで実現されているのですが)。
- ① htmxのライブラリーを読み込んでいます
- ② RailsではCSRF攻撃への対処用のトークンが必要になるので、ここで準備しています
- ③ ジャンケン・ボタンの記述
- hx-postでこのボタンを押したときに、POSTリクエストするバックエンドURLの指定
- ここではジャンケンの手をURLのqueryで与えています
- hx-includeは、POSTされる付加データを指定しています、ここでは②のトークンをジャンケンの手に付加しています
- hx-targetは、このリクエストに対するバックエンドからのレスポンス(対戦記録のHTML)を書き込むエリアをCSSセレククターで指定しています
- hx-postでこのボタンを押したときに、POSTリクエストするバックエンドURLの指定
- ④ 対戦記録が書き込まれるエリア
- ⑤ これは特殊なイベントを指定しています
- hx-getでこのイベントが発生した時にGETリクエストをするバックエンドURLの指定
- hx-triggerイベントの種類を指定します。
load
指定は、このページがブラウザーに読み込まれた時にイベントが発生します - hx-target ③で説明したのと同じです
<script src="https://unpkg.com/htmx.org@1.9.10/dist/htmx.js">
</script> <!-- ← ① -->
<h1>ジャンケン</h1>
<input type="hidden" name="authenticity_token"
value="<%= form_authenticity_token %>" /> <!-- ← ② -->
<!-- ↓ ③ -->
<button hx-post="/jyankens/pon?jyanken[human]=0"
hx-include="[name='authenticity_token']" hx-target="#list">グー</button>
<button hx-post="/jyankens/pon?jyanken[human]=1"
hx-include="[name='authenticity_token']" hx-target="#list">チョキ</button>
<button hx-post="/jyankens/pon?jyanken[human]=2"
hx-include="[name='authenticity_token']" hx-target="#list">パー</button>
<div id="list"></div> <!-- ← ④ -->
<!-- ↓ ⑤ -->
<div hx-get="/jyankens/list" hx-trigger="load" hx-target="#list">
jQuery
説明は省略しますが、上のhtmxと同じ事をjQueryで実現すると以下のようになります。htmxの動作が想像できるJavaScriptのコードになっていると思います。
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"></script>
<script>
$(document).ready(function() {
$.get("/jyankens/list", success)
});
function pon(te) {
const data = {
jyanken: {human: te},
authenticity_token: "<%= form_authenticity_token %>"
};
$.post("/jyankens/pon", data, success);
}
function success(data) {
console.log(data);
$("#list").html(data);
}
</script>
<h1>ジャンケン</h1>
<button onClick="pon(0)">グー</button>
<button onClick="pon(1)">チョキ</button>
<button onClick="pon(2)">パー</button>
<div id="list"></div>
まとめ
htmxは従来jQuery等で書いてきたコードのうち良くあるAjax等のコードをJavaScript言語を使わずにHTMLタグの拡張で置き換えてくれるライブラリーです。
世の中には、JavaScriptの嫌いなWeb系プログラマーもいると思います、そのような方はhtmxを使うと良いのではないでしょうか?
最後にhtmxホームページのEssaysにあるミームが興味深いので、ぜひ眺めてみてください。