Drab: remote controlled frontend framework for Phoenix

I like the sql’y syntax personally but I’d be fine with at:, I like most of the current syntax actually, I know I had a few changes in mind (like removing jquery, jquery is really not necessary, everything can be done with vanilla js pretty easily except some really odd selectors, of which there are better ways anyway) but I don’t remember most at the moment. ^.^;

There is one change that I would make though, I’d add a new action:

socket |> post(name_binary, value_anything_serializable_by_poison, into: selector//nil)

The reason would be is to update a global table of values with the name of whatever name_binary, so doing this:

socket
|> post("theName", %{blah: 42, bloop: "Hello world"})
|> post("theName.blah", 84)

Would set a global scope javascript variable (since the selector is nil by default) that would end up being the javascript {blah: 84, bloop: "Hello world"} in the global variable name of theName. If you pass in a selector then it sets those properties (not attributes, attributes you should append the name with a $) on the html elements themselves. This would follow the current style of webcomponents and allow controlling webcomponents far more easily. In addition you could add something like:

<span drab-set-body="theName.bloop></span>

Which when combined with the above post would make the span display “Hello World” in it.

You could even go further and do something like:

<span drab-wire style="height: [[theName.blah]]">Message:  [[theName.bloop]]</span>

Where when drab-wire is truthy on an element then it is ‘processed’ template-like, which basically gives you the polymer style templates that you wire up to values that the server controls, which gives you very fine-grained control and setting of things without needing a webcomponent library like polymer (should have a meta value that defines the template parts like [[/]] so it could be used with something like polymer by changing it to ((/)) or whatever the user wants per-page, or just default to ((/))?

It would be really cool to basically have a polymer-drab that is like polymer’s templating but controlled entirely server-side. :slight_smile:

Really should stop using jQuery. ^.^

1 Like

I can only support that statement. jQuery is something of the past and should not be a requirement for a new technology.

2 Likes

Thanks for those comments, folks. I have something to think about now :slight_smile:

About jQuery, Drab is modular and you don’t have to use it if you don’t want to. For now it is a default one, but I am planning to change it in a near future (and rename it to Drab.JQuery to give a space for a future non-jquery, first-choice default module).

I’ve chosen jQuery because it is easy and almost everyone knows it. And I just wanted to focus on the core of the library. And if you want to explain Drab in a short sentence, you can say “it is like jQuery, but server-side” :slight_smile:

@OvermindDL1, thanks for an idea of the polymer-drab. This is really interesting and it could be a core idea of a brand new Drab module. I think we could go a step further - we don’t need post function! What about if the following would just work:

<span drab-wire style="height: [[blah]]">Message:  [[bloop]]</span>

def clicked_some_button(_socket, _) do
  blah = "100px"
  bloop = "You are Drabbed"
  [blah: blah, bloop: bloop]
end

System could update the interface based on what the event handler returned.

1 Like

@grych Since you seem inclined to re-work some of the Drab syntax, I also recommend you look at the fusetools.com API for inspiration.

Fuse is a very young mobile SDK which makes a lot of previously hard things easy to do. https://www.fusetools.com/

1 Like

That would indeed be entirely possible. :slight_smile:

I quite like the template system in Polymer, it was designed to follow the WebComponents spec directly to the letter, which since it has been in flux a bit then Polymer has had a few minorly breaking changes with fallbacks in most cases for when it changes to match the spec again, but the spec is now pretty well set in stone, and the fallback to use unsupported browsers is just the webcomponent(-lite).js polyfill, which is used in quite a few libraries now including Polymer. :slight_smile:

Still need some way to specify if setting variables global to the app or local to the element though, that is a big thing in polymer, everything is scoped to certain ‘areas’, which makes you not need to worry about things. Perhaps do the same, have no global scope but you have to decorate (via an attribute) certain root nodes where scoping happens?

1 Like

Here you go: Drab: Server Side User Interface Access

It is not very sophisticated. Well, it is rather absolutely primitive :slight_smile: ! But I think it is quite well description how broadcasting works in Drab.

3 Likes

Nice one - I got a fright when you replied as I didn’t think it was a live demo :043:

2 Likes

@grych First i´d like to thank you for a great project you´ve started.

What is your roadmap for it? Are you committed to elixir / Drab on a long term basis or is it just something (Drab) you do for a proof of concept?

I´m coming from meteor and experienced many projects which ended up dead after a while.

2 Likes

Hey @Max,
I understand you concerns. One of the reason I made Drab is because the projects I’ve been interested in - first Nagare, then Volt Framework, were abandoned.

I consider Drab beyond the proof of concept - in the beta stage. Drab.Core API is stable now, I am not planning to change it. About Drab.Query, despite the comments in this thread, I want to keep the existing API. Drab has the integration (end-to-end) tests, documentation (could be improved, I know) and the tutorial. I am surprised myself how mature it looks :wink:

The rough plan for the future is:

  • minor changes in the next version, 0.3.5, described in TODO.md
  • head to 0.5.0, the next “major” release with the new main module (so make Drab.Query optional)

The new module in 0.5.0 is not to replace Drab.Query (it will stay and will be supported). I started with the jQuery, as it was the easiest way to archive my first goals - to prove it works, and it can be usable. Drab.Query is in fact just a bunch of helper functions, everything could be done using Drab.Core only; for ex the following function:

Drab.Query.select(socket, attr: :href, from: "#selector")

translates directly to:

Drab.Core.execjs(socket, "$('#selector').attr('href')")

The new main module will not rely on any existing JS library, it rather should be a new approach, more elixir/phoenix-like. I had some great suggestions in this thread, and I have some my ideas - I will be back with some RFC later.

Anyway, building Drab is not my full-time job, I am doing it on my free time only. Any help would be appreciated :slight_smile:

5 Likes

Hi folks,
someone asked me (on the Drab Chat!) how hard would be to add the presence list to the Chat Example. I found quite helpful to build it, as it seems to be a good way to teach Drabs onconnect and ondisconnect callbacks.

Here it goes: https://tg.pl/drab#presence

Again, please treat it only as a learning case. There are much better ways to track users presence in Phoenix :slight_smile:

4 Likes

@grych It’s ready for production? I don’t take a complete look because when I saw the readme tell us this:

Warning: this software is still experimental!

Any way looks pretty interesting, very good work here :smiley:

Hi @WolfDan,
I would say it is in the Beta stage now. I must change this warning some day :slight_smile:, it is still there since it was just a proof-of-concept. But the only real page I made with Drab, is the demo page.

To obtain a rough roadmap, please take a look on my answer to @Max above.

At this point I am still working on the twist to change the default library from inspired by jQuery to … something completely new :slight_smile: The next step would be going to production, by refactor some core code and eliminate know issues (two so far).

You are very welcome to get and try it! Every test counts.

2 Likes

All right! The projects looks simply awesome, just a few things…

  • Sometimes feel really slow:
    https://tg.pl/drab#simple you click and do pretty slow
    Drab Store and access to Plug Session “Show Counter Value” fells really really slow

Maybe its my internet or the server idk

  • What about SEO? I know its beta but edit meta on server and serve it I think its pretty possible on Drab

  • What about routing? Any thought about it, I always love the spa websites, can be cool a future plan for it


I think the potential of the project its awesome by the simple way that you can get data on server and show with on the web browser the same language that is coded the backend side! (Also have disanvantages, for example I can use Graphql for the project, absinthe just works for server side not client so I don’t have any way to use absinthe in this case [I speak in my ignorance, I do not know the whole library ^^])

1 Like

Hmm I never had an issue with the speed. Maybe because the server is in Europe and I reside now in Geneva. Before, the demo page was running on the old mac mini in my flat in Warsaw, connected with the cable operator, and I never observed any issue with the processing speed.

Anyway, the project needs benchmarking. It is on the todo list.

Do you mean SEO of the demo/tutorial page? Yep, should do at some point.

BTW, I am not the best in inventing the catchy phrases. “library for server-side DOM access”, “server side UI access”, “the jQuery in elixir”, “Access the browser User Interface from the Server Side” is the only I could find out. I need something brief and short (like legendary “Productive |> Reliable |> Fast”). Help needed!

Routing is done by Phoenix. Drab, by design, works on the Single Page only. It is not a framework, it is an addition to it.

Your demo page is very non-immediate for me as well, yet my local site is pretty instant. I’m in the USA so I just chalk it up to normal latency as the page itself takes a second before it loads anyway. ^.^

Which is why I think integrating an Unpoly.js thing into it would be fantastic!

I mean server side render, for thing like metadata (description, title, etc…)

This!!! +1

1 Like

Rendering is always done by Phoenix! Of course you can update meta or title with Drab, but google will never see it :slight_smile: Drab works after the page is rendered.

Please be patient. The new idea is coming :slight_smile:

1 Like

I guess that’s the issue. It is fine to wait 1 second, when you click the uppercase me example. But, if the server reads some values from the browser while handling an event, and every read is about a second… we have a problem.

This is what I want to solve with the new library. Rather than using DOM as a database, like Drab.Query does, it should cache it for reading on the server-side, and push the changes only on demand.

The other question is, how this latency compares to the similar AJAX call. This needs to be benchmarked.

That would explain why a lot of it is slow. ^.^

Need to batch commands then!

1 Like