Update 28 Sept 2008: checkout the working code at github repository, and a short video demo on vimeo.
I've been swimming in jQuery-bliss for a few months now - thanks Divya & Tien Dung for introducing me to it! I'm yearning to do it on the server-side.
But to enjoy the jQuery-bliss (aka "no special case pattern"), I'd need to be in a problem where I have a document to sculpt. My recent toys (cleartz and tryanslator.. and actually most Javascript apps?) for example, are built the via sculpting way: a very basic HTML structure, then Javascript comes in to flesh out its form and introduce function. A very pleasant development experience overall.
Aside: Back in Java days, I remember I used to hate XML DOM parsing a
lot. NodeList? hasChildNodes? But XPath came and suddenly pain became pleasure.
On the server-side, Model (of MVC) stuff seems to fit (maybe sqlQuery( "people[gender='Male']" ).update({ salutation: "mister" }) ?) but ActiveRecord (& Ambition?) is already nice to work with, and I have no major problems there.
My gripe is with the View (and consequently the Controller). Views are generally powered by some templating system. These gnarly things are just a pile of bastardized HTML files good for neither designers nor developers. The best templating systems are only best because you'll choke yourself slower by using them. Anyways, pretend you agree that templates == bad.
Wouldn't it be nice if your web framework 1) loads up pure HTML as a document object, 2) you modify them in the jQuery-bliss way in your Controller, then finally 3) the resulting HTML is spit back to the client browser?
No nasty <? %> } or custom syntax for dynamic content, or loops, or if-else. Just pure HTML with dummy data baked in.
# display_user.html
<span class="tel">
<span class="type">home</span>:
<span class="value">+1.415.555.1212</span>
</span>
Then modify them before serving:
# inside controller
def display_user(doc)
user = User.find( params[:user_id] )
(doc/".tel .value").inner_html = user.phone_number
return doc.to_html
end
And because it is an in-memory tree instead of some opaque String, you can do everything programatically around the document: looping, if-else, removing nodes, replacing sub menus, partials? Furthermore, when you need to do dynamic behaviors on the client-side, the programming paradigm is exactly the same!
Designers can be happy churning out the HTML/CSS in whatever tool they like (be it Dreamweaver or notepad.exe), and developers just poke their DOM.
What say you?
PS: Oh well, I guess what I'm trying to say is maybe we should not waste time finding better ways of constructing webpages (i.e. templating systems) when we could approach the problem as "modifying a document" - which is much cleaner and (with the right API) much easier.
Interesting idea.
However, I try and do as little in the view as possible and make as much use of partials as I can to try and achieve usable templates. Executed properly, you can get decent readable templating but sadly without your JQuery-syntax nirvana.
Looked into Presenters?
Posted by: Andy Croll | March 26, 2008 at 07:45 PM
I really like the ideia, I've worked before with something like this with the TYPO3 CMS and its Futuristic Template Builder, where you get the template from the designer full of dummy data and unzip into the templates folder. And then, you select a html file from that zip and visually map/link the dom nodes to the application content areas and it's done. you get a dynamic website without touching the template html.
But now, I'd prefer to convert the template to haml (html2haml) and keep it clean.
Posted by: Marcus Derencius | March 26, 2008 at 08:23 PM
@andy: The concept of partials (i.e. reusable, smaller building blocks) would apply for what I've described. Just that these partials are plain HTML, no special constructs within.
Presenters are 1 layer too much for me personally. Reminds me of the days of doing facades in j2ee...
@marcus: that visual-template thingy sounds gimmicky! but i'm sure the "unzipping html and it works" part feels great.
while I appreciate HAML's fresh approach, the designer/developer gulf is still there (if not worse)
Posted by: choonkeat | March 26, 2008 at 09:33 PM
Cool idea I agree. But won't this be substantially slower than templates? Inside a browser, DOM creation will be drastically faster (implemented in C and lots of optimization). I'm not sure how fast you can build a DOM-like tree in pure Ruby by parsing through the template. And worse yet, this has to happen for every single request.
I don't know about Rails but the Django Template language is specifically designed so that the entire template can be parsed really quickly by just using regular expressions.
Btw are you overriding the behavior of the "/" operator on the doc object in order to achieve that cool syntax? It always amazes me how Rubyists create these tiny DSLs cleverly!
Posted by: Harish Mallipeddi | March 27, 2008 at 12:58 AM
@harish: there's no reason why a server-side parser can't be as C and as optimized :-) the only thing client-side Dom parser has (over server side) is using somebody else's CPU.
i'm using _why's Hpricot library in the example and the "/" operator is his genius at work. I guess he's not happy writing Hpricot(".tel .val", doc). btw, Hpricot happens to be a plenty fast parser out of the box
Posted by: choonkeat | March 27, 2008 at 01:44 AM
You know that is a great idea. Most people use this process while approaching web app creation, i.e. create all pages possible using HTML+CSS, insert the relevant within them to make them dynamic web apps!
The only issue is then how to find which elements to replace? Is this what u suggested? the designer can be given a set of classes that he/she needs to apply to the container of a particular data and then some parser can convert it by matching that class to the data.
I think RoR even now generates id for form elements through the name given during the (sorry I am stating this very badly!). We can sort of do the reverse.
Posted by: Divya | March 27, 2008 at 08:28 AM
There is a templating engine for Rails called Lilu that does exactly this. Here's a write up on InfoQ http://www.infoq.com/news/2007/07/mockup-driven-dev-lilu, but that's a bit old. I believe the API has been cleaned up a bit since then. The only drawback right now is that it is significantly slow (according to the author).
The author did stop by the Malaysia.rb mailing list to answer some questions. http://groups.google.com/group/malaysia-rb/browse_thread/thread/bec1d5593b3e24fd/f603651d57ea583a?lnk=gst&q=lilu#f603651d57ea583a
Posted by: Kamal Fariz | March 27, 2008 at 09:28 AM
@divya not just that. developers usually have to convert the designer's HTML into templates (manually) and it becomes a 1-way street: 1) designer says bye and leave, 2) designer learns templating language (yuck) to continue support, or 3) both parties work on different files (which is hell).
This proposal means that the files designers edit/create are *used directly & as-is* by the application.
Programmers are used to this benefit: The source code they edit/create are used directly & as-is by server. Even when it is compiled to something else (e.g. JSP) the process is automated and edits don't go there. Why should it be worse in the design side of things?
Posted by: choonkeat | March 27, 2008 at 09:42 AM
@kamal: thanks for the pointer! Lilu looks like it has gone down this path indeed. Will investigate its learnings and viability.
Posted by: choonkeat | March 27, 2008 at 10:28 AM
Lilu looks interesting. Do you guys know what library it uses underneath to parse and build the DOM?
If we make this compatible with the jQuery-selectors API (http://docs.jquery.com/Selectors), I can see how this can be a lot of fun :)
Posted by: Harish Mallipeddi | March 27, 2008 at 12:33 PM
@harish: checkout its git repo. looks like Hpricot.
Posted by: choonkeat | March 27, 2008 at 03:32 PM
Great idea! I think it's amazing. It reminds me of (surprisingly) Seaside, the Smalltalk web framework. That went down another path in which the programmer has total control of the HTML (there is no template) from the backend and the designer only generates CSS.
On the other hand I think most of the problems between a designer and a programmer boils down to communications between human beings. I believe hquery is a clever and effective way if both designer and programmer follow the same standards and have the same understanding of web design.
Posted by: Sausheong | October 01, 2008 at 10:05 AM
Such idea is implemented in QueryTemplates, here's some sample:
template('myTemplate')->parse('input.html')->
find('.my-div')->
ifVar('showMyDiv')->
find('ul > li')->
loopOne('data', 'row')->
// line below will rapidly populate template with data from $row
varsToSelector('row', $rowFields)
Significant difference is that it produces native executable code and DOM manipulation have to be only done once. You can check it out here:
http://code.google.com/p/querytemplates/
Library itself is written in PHP, but it can produce code in various languages - PHP and JS right now, but Ruby and Python are on the TODO list. Syntax is quite simple, because most of it is inherited from jQuery (thx to phpQuery).
If some of you were interested in Ruby-code generation support, here's the ticket for it:
http://code.google.com/p/querytemplates/issues/detail?id=4
Such enhancement can be quickly implemented when demanded by the community. Ruby uses can help just by writing ruby code of example final template.
Posted by: Tobiasz Cudnik | February 22, 2009 at 06:59 PM
@tobiasz cudnik: in case you missed the update, my proof of concept in production (demo: http://www.vimeo.com/1836815 )
i'm thrilled to see the exploration of similar ideas on other platforms. perhaps we can have a stronger voice by striving to use the same vocabulary to describe this approach? i'm currently using "unobtrusive server script", based off http://en.wikipedia.org/wiki/Unobtrusive_JavaScript
Posted by: choonkeat | February 23, 2009 at 08:22 AM