Symfony Advent Calendar 2021 day15の記事です。ギリギリセーフ!のはず!

6月にSymfony World Summerで発表されたsymfony/ux-turboをようやく触ってみたのでハイパー軽くご紹介します。(ちょうど先週のSymfony World Winter開催期間中にSymfonyUX2.0もリリースされました。 https://symfony.com/blog/symfony-ux-2-0-and-stimulus-3-support

symfony/ux-turboは hotwired/turbo-drive https://turbo.hotwired.dev/ をSymfonyアプリケーションに統合するためのブリッジライブラリです。
The speed of a single-page web application without having to write any JavaScript. つまり、JavaScriptを書かずにSPAのスピード感を出せるよ!というコンセプトです。早速やってみましょう。

この記事のサンプルコードは https://github.com/77web/symfony-ux-turbo-playground で公開しています。
単純なタスク管理アプリで、タスク追加のみができます(タスクを完了させる機能もまだ作ってません… :sweat_drops: )。normal-symfonyブランチの時点までは普通のSymfonyアプリケーションと変わりません。

normal

symfony/ux-turboを追加

composer require symfony/ux-turbo
yarn install

config/packages/webpack_encore.yamlの設定をturbo用にする

# config/packages/webpack_encore.yaml
    script_attributes:
        defer: true
        # Uncomment (also under link_attributes) if using Turbo Drive
        # https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change
-        # 'data-turbo-track': reload
+        'data-turbo-track': reload
-    # link_attributes:
+    link_attributes:
        # Uncomment if using Turbo Drive
-        # 'data-turbo-track': reload
+        'data-turbo-track': reload

twig上でタスク追加フォーム部分をturbo-frameで囲む

# templates/default/index.html.twig

<h1>Add a task</h1>
+<turbo-frame id="task-form">
{{ form_start(form, {action: path('app_default_new')}) }}
{{ form_widget(form) }}
{{ form_end(form) }}
+</turbo-frame>

変更したのはtwigだけです :sweat_smile:
この状態で動かしてみると…

turbo

先ほどの通常Symfonyアプリケーションのときと比較すると、ページ全体がリダイレクトしていないため、上部のタスクリストにいま追加したはずのタスク xxx が表示されていません。
しかし、データベースを直接見てみると xxx 追加自体は成功しています。

+----+-------+--------------+
| id | title | completed_at |
+----+-------+--------------+
|  1 | test  | NULL         |
|  2 | aaa   | NULL         |
|  3 | vvv   | NULL         |
|  4 | xxx   | NULL         |
|  5 | yyy   | NULL         |
+----+-------+--------------+
5 rows in set (0.00 sec)

ブラウザの更新ボタンでページ全体を読み込み直したら、タスク xxx がリスト上に出てきました。
reload_after_form1

つまり、turbo-frameで囲った部分のみが再読込されて、SPAのように部分更新が行われていたわけです。確かに、約束どおり(?)私はJavaScriptを一行も書いていないのにSPAみたいな体験ができました! :tada:

まとめ

JavaScriptを書かなくてもある程度SPAっぽいこともできますし、多少のJavaScriptを書いても良ければもっと色々なことができそうですね :relaxed:
symfony/ux-turboを使ってチャットを作るかんたんなチュートリアルがsymfony/ux-turboのREADME https://github.com/symfony/ux-turbo#readme にあります。

複雑に変化するフォームであればAngularでフロントエンドを書いてしまうほうが早いのですが(最近はPHPチームもAngular書いてます 😅)、ちょっとしたステータスポーリング等であればturboでも良い気がしてきました!!