Skip to content

Jinja+htmxからhtpy+data-starへの移行#106

Merged
exflikt merged 3 commits intotut-cc:mainfrom
exflikt:datastar+htpy
Apr 30, 2025
Merged

Jinja+htmxからhtpy+data-starへの移行#106
exflikt merged 3 commits intotut-cc:mainfrom
exflikt:datastar+htpy

Conversation

@exflikt
Copy link
Collaborator

@exflikt exflikt commented Apr 29, 2025

動的HTML生成するJinjaテンプレートをhtpyへ変更

理由: Jinjaはファイル単位で記述するため、再利用性や構成容易性に難があった

  • htpyはHTMLコンポーネントを変数、関数、クラスで定義できる
  • HTMLの属性値を関数呼び出しで、子要素を配列アクセスで記述する:
    __call____getitem__ のオーバーロードで実現している
  • 構文自体は純粋なPythonと何ら変わりないので、コンポーネント管理しやすい:
    JSXのように、HTMLをデータとしてではなくコードとして管理できる

サーバへのリクエストロジックの記述をhtmxからdata-starへ変更

理由: htmxは複雑なリアクティビティを実現しようとすると属性値が多くなり、メンテナンスコストが上がるため

  • data-starは、スワップ方式をサーバ側から指定できる
  • HTMLコンポーネントだけでなく、signalで文字列データを送受信できる
  • AJAXリクエストのパラメータやテキストノードをsignalの値に設定できる
  • 複数のHTMLコンポーネントを置き換えられるhtmxのoob-swap (out-of-band swap)がデフォルト:
    サーバ側の裁量で複数のコンポーネントを任意のタイミングで置き換えられる

htpyとdata-starを採用することで、HTMLをコンポーネント単位で記述することが容易にできるようになった。このおかげで、ページ数が増えてもスケールしやすいコードベースになったはず。

exflikt added 3 commits April 29, 2025 17:32
I am too lazy to split the changes of this scale.

This commit introduces htpy and data-star to rewrite Jinja templates and
htmx attributes, respectively.

*Jinja* -> *htpy*

htpy is a library for writing HTML using plain Python syntax. Given
elements like `div` and `li`, we can specify attributes in function
calls `(attr=value)`, and child elements in `[]` syntax. htpy achieves
this by overriding `__call__` and `__getitem__` dunder methods. This
effectively builds an intermediate representation for HTML using Python
lists and dictionaries. Then, this object can be converted to HTML while
also escaping Python strings via MarkupSafe library which Jinja also
uses internally. Although the syntax is quite different, the underlying
philosophy aligns with that of JSX, which treats HTML as code rather
than data.

The reason I switched from Jinja templates is that htpy integrates well
with the Python language. Whereas Jinja templates are defined in files,
htpy can use a function to define a component. We can even use a
variable or class for defining HTML components. The ability to treat
HTML fragments as code is similar to JSX, and feel like this is more
maintainable in the long run.

One down side of htpy is that it is relatively slow compared to Jinja.
This is because Jinja uses its own compiler to cache template loading
and reduce the cost of rendering. But since htpy already has the
intermediate representation, I think a writing a compiler would be
doable and benefit more from the context-sensitive optimization of HTML
fragments, which Jinja cannot benefit from due to the design constraint
that the Jinja templates can be language-agnostic.

*htmx* -> *data-star*

data-star provides htmx + Alpine.js experience, but in a more cohesive
way. It manages state and reactivity through HTML attributes while at
the same time allowing backends to modify DOM and the state by sending
events.

htmx often suffers from attribute explosion (e.g. specifying hx-post,
hx-trigger, hx-target, hx-swap on the single element). In data-star
however, all those target and swap logic is dictated by the server-side.

Also, the package size of data-star is smaller than that of htmx :)

*Other changes*

There are many small insignificant and important changes (like,
Broadcaster class in `app/bc.py` to manage notification events) made
here and there.
@exflikt exflikt marked this pull request as ready for review April 30, 2025 09:48
@exflikt exflikt merged commit 8493f81 into tut-cc:main Apr 30, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant