When the /vapps and /qapps screen render modes were made, the main objective of them was to allow client reactivity in Moqui. Actually creating these render modes was a large challenge, and contribute to a large fraction of Moqui’s complexity. As I’m migrating from vue 2 to vue 3, I’m contemplating that there might be a better way to handle client reactivity without requiring a fancy javascript framework.
Htmx
One potential is a library that has had a recent surge of interest from the web community in back end apis. Tech twitter seems to be completely enamored with htmx which reached #2 in the 2023 JavaScript Rising Stars “Front-end Frameworks” category.
Htmx allows you to add attributes to any html element to query a server for html. This way your templates can be rendered on the server without having to replicate state and logic on both the client and the server. It has a simple api that allows for reactivity in web applications.
The example that made me realize why this is so helpful is the hx-swap attribute. If you have a menu bar to the side, and an screen rendered to the right. The menu bar is a list of elements like
<div id="menu">
<button hx-get="/order" hx-target="#response-div" hx-swap="innerHTML">Go to Orders</div>
<button hx-get="/party" hx-target="#response-div" hx-swap="innerHTML">Go to Parties</div>
</div>
<div id="response-div">Choose a Screen</div>
Then when you click on “Go to Orders” the /order endpoint returns html and the #response-div gets replaced.
There are many more examples for this here.
Ruby on Rails
As I’ve thought about the web framework part of Moqui, I thought that looking at how other web frameworks handle javascript, client side interactivity, and mobile would be helpful.
Ruby on rails is similar to Moqui in that it uses templates to inject html with data. A good example of this is the rails Action View Form Helpers. Where it differs from Moqui is generating templates within templates. In rails, it is fairly trivial to have a template within a template that can be reused in multiple templates. (While this is possible in freemarker, the default in Moqui is to not edit the freemarker files for screens.)
Javascript Bundling
Ruby on rails has been shipping different ways to handle javascript for web apps. In rails 7, there are 3 ways to handle javascript.
One is import mapping (most similar to Moqui), which is a cli application that allows you to add es6 native esm modules to your application javascript through a cdn. This requires no js runtime at all and uses HTTP/2 multiplexing on queries to have minimal overhead when serving many files. This also allows for a typical import { createApp, ref } from 'vue'
type syntax. Import mapping does not have any transpilation and uses browser native technology (with polyfills) to have a great experience on all actively supported browsers (after Microsoft finally dropped support for IE 11).
jsbundling-rails supports typical js tools by using a js runtime like node / bun to transpile and bundle using common build tools like rollup, esbuild, webpack, and bun. Then, the output gets directly added to the rails asset pipeline that will transform images, javascript, and other typically static files to the final product suitable for production use in rails. This way the latest node ecosystem features can be used like typescript while still having one server to deploy the app onto. This kind of functionality seems like a promising short term feature in Moqui to get javascript ecosystem developers developing a UI in Moqui.
The last option is to just use Rails as an API, and have a completely seperate server running all the client logic in any front end framework like Next.js or flutter. This is what most custom UIs in Moqui are currently doing.
Hotwire
Right now in Moqui, if you want to develop a mobile application using a similar UI, you would need to port all the components, ftl template logic, and screens to a Quasar CLI application. This is quite unfeasable, and is probably not worth using any existing Moqui screens for a custom or existing app.
There is another way that mobile could be done using the existing Moqui logic (with some hacking ofc). This would be implementing something like hotwire. Hotwire is a set of libraries that extend rails to stream HTML to the client instead of JSON. Hotwire consists of 3 libraries: turbo, stimulus, and strada.
Turbo has 4 parts: Turbo Drive, Turbo Frames, Turbo Streams, and Turbo Native. Turbo Drive and Streams together are similar to htmx, they allows for specific dom updates on javascript events for full or partial screen updates over http or websocket using html element parameters and minimal javascript. What Turbo does differently is Turbo Native enables for hybrid applications for iOS and Android out of the box. Turbo Frames allows for a certain screens to have an independent context which can be used similarly to Vue components. That isn’t nearly enough to go over everything in Turbo, but that should give you a good enough idea.
Turbo only handles 80% of the uses cases. Stimulus is a simple javascript framework for treating html output like ruby controllers for when server side javascript doesn’t quite cut it.
Strada the bridge between web components and native components in hotwire.
Overall hotwire is an interesting approach and could be used to stream html down to mobile applications.