pydantic / FastUI

Build better UIs faster.
https://fastui-demo.onrender.com
MIT License
7.92k stars 302 forks source link

HTML + HTMX frontend - AKA Jinja frontend #48

Open samuelcolvin opened 8 months ago

samuelcolvin commented 8 months ago

The swifties of HTMX on twitter are asking "why not HTMX?".

While I'm not as enamoured by HTMX as some, there is a good argument to build a frontend that requires no javascript, with optional improvement via HTMX.

The main advantage as I see it is to end users of the applications - less JS to download, less chance of clientside bugs that go unfixed, less chance of something built with this silently breaking in 10 years time when the maintainer is dead.

The real question is how to render the HTML, there are three options:

  1. Jinja2 (or other python template rendering engine), running as middleware or a reverse proxy to take models returned by the endpoint and render them to HTML
  2. something at the edge that takes the models and renders them to HTML, I tried to build something like this 3 years ago using wasm but the performance was too bad, AFAIK that's still an issue unless the app is very high volume, so you'd need to somehow render the HTML with pure javascript and no eval, doesn't sound easy, though it would be awesome
  3. I have a very experimental template rendering engine that uses JSX syntax and is written in Rust with Python bindings called psx, maybe one day if I get rich or end up in prison I'll finish it

In the mean time, the only realistic way to do this is option 1.

Are there are python bindings for one of the rust ports of jinja, like minijinja? (@mitsuhiko I seem to remember you talking about this on twitter, does it exist?)

Rather than middleware or a reverse proxy, we could have a function that renders the HTML at return time, so you do something like

@app.get('/api/')
async def my_view(...) -> HTMLResponse:
    components = FastUI(root=[...])
    return render_fastui_response_with_template_engine(components)

One very nice feature of returning JSON from an app is that unit tests are far easier than when returning HTML, therefore whatever solution we end up with (if we end up with on at all 🤷), we should be able to switch off the rendering and return JSON for tests.

ischaojie commented 8 months ago

Are there are python bindings for one of the rust ports of jinja, like minijinja?

The answer is yes: https://github.com/mitsuhiko/minijinja/tree/main/minijinja-py

stephenangeloni commented 7 months ago

If "render_fastui_response_with_template_engine" finds a template for the json response based on verb:path (here GET:/API/) then it would be easy as pie to match templates to paths to restitute HTML (or any other format for that matter.) in templates/API/ you could have get.html, get.yaml, get.xml, post.txt, delete.yaml and when unambiguous (only one version of the verb) use that format or if ambiguous as in GET in this example have an optional parameter to express preference in "render_fastui_response_with_template_engine" or use an environment variable that establishes precedence.

Whatever the rendering engine, a DEBUG switch to push to the browser the source/components/template used to show a piece of code/script/data in the browser would help tremendously in working up the chain to understand the production of the page at any stage.

Give the ability to add meta data to the components for use by the rendering engine or CSS in the webpage is also a must. It gives the ability from the backend to allow the frontend to differentiate between same components in presentation if the frontend developer chooses.

I think I'm going offtrack :-)

Just love this idea, as it allows precisely what HTMX is aimed at, real REST and progressive enhancements.

I'll try to help. I'm a bad developer with ideas(the most dangerous kind), but nothing a good code review wouldn't catch before a merge.

Thanks

fsadatl commented 7 months ago