Drab: remote controlled frontend framework for Phoenix

Drab is made in such a way that everything is compartmentalized. I’m not even using any of it’s main accessors right now as I’ve built’ish my own to work with the Unpoly.js library. :slight_smile:

1 Like

If you mean user authentication/authorization - there is none. It is not in the Drab’s scope. If you mean how user may tamper with requests (running event handlers in the controller) - I built it with security in my mind. There is always a token, values stored in the client side are always signed.

For the new module, Drab.Live, where you can update assigns you had in the template, live - all the expressions are stored in DETS on the server side, so the client knows only hashes of them.

Magic is good!
As a first step of Drab, I’ve created an API to have the jQuery methods on the browser side. Not very easy to learn, even I need to take a look on docs from time to time. No magic, just work.

Magic is coming in the second step (upcoming v0.5.0):
Imagine you’ve rendered the template in the controller. This page is now showed in the browser. And magically, using Drab.Live, you may update your assigns, remotely. No need to change the template, no need to learn a new framework, except two functions peeking and pokeing your assigns from/to page. Minimum to learn.

First functionality is already working, check out https://tg.pl/drab/live.

2 Likes

I was not very impressed with this drab stuff, but I am veeery impressed with the LiveController API. This is some magic I can get behind.

1 Like

This might be a stupid question, but does the live controller work with if expressions (as it does with for expressions?) if so, then this replaces 90% of what I use VueJS (a JS framework) for. The other 10% are preserving the cursor position in a textarea when the UI changes…

Yes. It works with any Elixir expression.

There will be some limits, but on the html side: it expects the proper html in the template, as it needs to parse the template during the compile-time, when to decide if the expression is an attribute, or inside a script.

I have to start learning drab, then. Is it very resource intensive to keep the channel open so that you can manipulate the DOM? In terms of latency, of course, nothing beats client side JS, but for things that must talk to the server Drab doesn’t add any latency.

My only worry is the fact that I need to keep the channel open. I’m used to the “fire and forget” module of python’s frameworks, in which you send the request and forget it exists.

Am I right to be “worried”?

I’m used to those limits from VueJS templates, so that doesn’t bother me much :slight_smile:

Not really, it is just a normal Phoenix Socket/Channel.

Rather than ‘not really’, let me say: Really not! Persistent connections is what Elixir/Phoenix excels in, in respect to other webframeworks out there. Because of the preemptive scheduling used by the BEAM (the Elixir virtual machine), when some connections are slow or hang, the rest of your system will remain performant and degrade gracefully under heavy load. Solid Ground by Saša Juric is a presentation that goes into more detail about how this works :slight_smile: .

3 Likes

Thanks for the link to the talk :slight_smile:
I’m continuously amazed by how intuitive elixir is, compared to everything else I’ve tried.
Want to know what’s taking so long? Just ask the system!

The BEAM runtime is really amazing, and I wonder why it’s not more popular, especially with something like Elixir as a frontend

Thanks for the responses!

Can someone put up a quick demo of unpoly and drab live on github? i’d love to see how they work together as I’m considering abandoning Elm.

Another area I am wondering about is mobile. How would this work for a mobile app?

1 Like

Nothing special there, it is backend communication, not CSS or a rendering library. ^.^

1 Like

does master on github have a working Drab.Live module? Trying it out and not able to get it working with the example code from tg.pl/drab/live.

Yes, it is in the master. If you want to play with this, there is a test Phoenix App in test/support configured to work with Drab.Live. Warning, on this stage it is a sandbox for me, so please forgive the mess :wink:

Using Live in the external application requires some configuration, like define Drab Template Engine, etc. It will be described with v0.5.0, soon.

Hi guys,
news from Drab.Live world - living scripts. Every <script> in the template, which has any elixir expression with assign(s), will be re-evaluated when the assign changes.

Example:

<script>
  document.querySelector("#growing_button").style.height = "<%= @button_height %>px"
</script>

Change the value of @button_height assign - in the Commander, or directly in IEx:

poke socket, button_height: 100

And - voila - button changes its size :slight_smile:

As usual, I’ve created a demo https://tg.pl/drab/live#scripts

Next in Drab.Live

Special form for node properties (@OvermindDL1 - style):

<tag @property=<%= @assign %>>
<tag @property="string template with <%= expression %> inside">
<tag @property.deeper=<%= some_function(@assign) %>>

Notice I am going to use @prop= instead of prop$=, so it will not mess with JS libaries.

Work with partials - updates only within the partial:

poke socket, "user.html", name: "Mirmił"
poke socket, "web/templates/users/user.html.drab", name: "Łamignat"
3 Likes

Living scripts are pretty cool. Just be sure to add a warning saying that “Drab doesn’t understand or parse javascript, and the entire script will be rerun no matter what”. I can see some people shooting thenselves in the foot over this :slight_smile:

2 Likes

i added a repo with a fully working app and a small guide here: https://github.com/jschoch/drab_test_app

I may do an example for unpoly if anyone is interested in a quickstart.

2 Likes

Properties Syntax finished. Now you can assign any Node property with any Elixir expression by simple:

<button @style.backgroundColor=<%= gen_css_color(@color) %>

You may use the full path to the property

Like style.backgroundColor or anything valid.

The expression must return JS encodable value

Unlike the attributes (string only!), other JS data types are allowed. Under the only condition: they must be encodable to JS (using Poison).

Case Sensitivity is preserved

Although html5 properties are case insensitive, Drab preserves it. So you may freely use @style.backgroundColor

There can be only one

The only allowed syntax is to bind single property with single expression. No String patterns allowed. This means that instead doing:

<tag @style.height="<%= @height %>px"> <!--- WRONG PROHIBITED BAD DO NOT TOUCH DOES NOT COMPUTE-->

you must do:

<tag @style.height=<%= "#{@height}px" %>> 

As usuall, there is a new simple example: https://tg.pl/drab/live#properties

2 Likes

can you share some examples of your unpoly accessors? I was trying to get a modal button working but it does not seem hook the drab-click event correctly when in the modal view. viewing the page direct works fine with drab so i’m not sure what you did to make these work together.

i made a bit more progress but it seems like a hack:

this doesn’t seem like the right approach though. Seems i need some hook to tell unpoly to have drab run it’s evaluation after it pulls down it’s selector.

exec_js works fine to close the modal here

but then the “logout” button isn’t tagged correctly.