critique of vibe.d

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 10 06:42:30 PDT 2014


On Thursday, 10 July 2014 at 07:56:43 UTC, Jacob Carlborg wrote:
> To me that sounds a bit backwards.

I can go both ways, depending on the design of the form and how 
many helper tags we decide to use for the project.

My dom library doesn't dictate how you do it, of course, it just 
provides access to the html structure and has functions to help 
build one. But among the functions I've written for this are:

createAutomaticForm, which is found in my web.d module. It takes 
a D function signature and creates a form to call it, using 
static type info to generate the appropriate inputs.

This is a really old demo but still shows the principles:

http://arsdnet.net/cgi-bin/apidemo/add-some-numbers

That form is generated from "int addSomeNumbers(int a, int b);" 
The URL routing, field names, and types are pulled out of the 
identifiers used in D.

http://arsdnet.net/cgi-bin/apidemo/get-a-box

This one is "Element getABox(Color color);" with "enum Color { 
list here... }". Enums are rendered as <select>.



I find this is really convenient to quickly throw something up 
(web.d will do it automatically for any exported function that 
doesn't have a custom form function), but real web designs tend 
to need more flexibility so it doesn't do everything.


I have three other solutions too:

1) Just write the HTML form manually and fill it in with dom 
helper functions. This has become my preference in a lot of 
cases, it is really easy.

<form id="foo">
   <input type="text" name="field" />
   <textarea name="other"></textarea>
   <select name="auto_list" 
data-options-from="some_backend_item"></select>
   <select name="list">
      <option value="whatever">Cool</option>
   </select>
</form>

And so on and so forth. A lot of people don't like html, but I 
don't mind it at all; especially once you start using html5 
attributes, it is fairly concise for this stuff.

Another thing I like with this is the designer can write it with 
just a plain browser, no need for the whole backend 
infrastructure just to see some quick tweaks. Helps a lot when 
they are working offline too.

Filling data is easy. Either use the functions directly:

auto form = document.requireSelector!Form("#foo");

foreach(k, v; your_data)
    form.setValue(k, v);


Or, if you are using my database.d with dom.d, relatively recent 
versions include a fillForm function:

fillForm(form, your_object, "object_name"); // object_name is 
used if the function takes a struct rather than individual items 
- another relatively new feature


To fill in data from a form, you can most easily use my 
DataObject class from database.d which doesn't take a hash 
constructor like Ruby but with foreach, it is close enough:

auto obj = new DataObject(db, "table"); // you could subclass it 
for a specific table, database.d even has functions to generate 
those classes from MySQL CREATE TABLE declarations automatically

foreach(k, v; cgi.post)
    obj[k] = v;

or you could easily enough list the expected keys in that filling 
loop, kinda like the Rails strong params (as I understand them - 
rails is now my day job but I'm still a bit of a n00b).



Filling the form data and generating the model updates was the 
most painful part of writing PHP IMO, so dom.d made them all 
stupid simple. Now I don't feel the need for form helpers, the 
DOM is smart enough to fill in the gaps from whatever it is given.

dom.d also has a function to get a value hash out of a form but I 
never actually used it. Maybe with local imports, I can make that 
smarter and selectively depend on cgi.d to actually have it cool. 
I gotta come back to this stuff some day.


2) Generate the HTML with the DOM library along with helper D 
functions to ensure more consistency.

auto form = cast(Form) Element.make("form");

form.addField("name", "value", [options]);

addField has several overloads that pick the right HTML to make 
from a given data type. It generates consistent HTML for labels 
and spans so it is easy to style with CSS.

But since this is D, it is a bit harder to pass to a HTML guy to 
edit the design. Otherwise though, dom.d's helper functions make 
all kinds of manipulations really easy and it is tempting to use 
more than I probably should.


3) Some hybrid, where you use custom tags in the HTML which are 
run. dom.d's more recent versions also include passing <%= %> and 
similar tags to a handler, if we really wanted to, we could use 
scripts there as well as custom tags and data attributes to fill 
things in.

Early on, I used a LOT of custom tags, but nowadays I prefer to 
stick to mostly standard HTML so it works better stand alone.

> The view uses appropriate names for the form fields, scoped in 
> the same name as the model, like this:

Yeah, that's pretty nice. database.d's fillData (on which dom.d's 
fillForm is based and web.d does the same for struct arguments) 
just uses dots:

name="person.name"

which would fill the

void handler(Person person);

person.name field there. Then you do person.toDatabaseObject (an 
auto-generated function btw) to get a SQL builder class out of it 
and modify it if you want then finally just 
person.commitChanges(); which is like Rails' .save!

Perhaps I'll make the mixin just throw in a save method at some 
point too.



This stuff is fairly new and underdocumented/advertised, even my 
by lax standards. I think this is the first time I've even talked 
about it on the forums.


tbh from what I've seen, my collection of stuff is closer to the 
"full web framework" than vibe.d itself - as we discussed a 
couple months ago, I also have my SASS like css expander (which 
unlike the real sass doesn't need the rest of your life to 
recompile after any trivial change... though it is admittably 
still slow for D), javascript expanders and generators, various 
SQL backends, the list goes on.


More information about the Digitalmars-d mailing list