Friday, 30 March 2007

Golden nuggets

There's a lot of useful discussion going on over the seaside mailing list at the moment, triggered off by a question from Andreas Raab asking about some of the mechanics of Seaside. Some key points that were interesting to me:

A component is responsible for generating a part of the html of a "page". This includes forms, since they are part of html (note that you must not nest forms, forms really suck in html). The (visible) part inside the <body> is generated in #renderContentOn:. The part in the <title> is generated in #updateRoot: (create your metas here).


CSS depends on your needs. There are about three different ways for different situations. In general you assign the correct classes and ids to your html elements and the CSS comes from "somewhere" outside. You will have to write your CSS by hand (or let it write) Seaside doesn't help you there. It just gives you a choice where to put it.


Seaside doesn't have "special rules" but it does (by default) use a convention to make this stuff a little safer. Normally, the transition from one page to another is split into two request-response cycles. The first triggers the callbacks associated with the link or form elements, and Seaside sends back a 302 response, redirecting the browser to another url. The second request triggers no callbacks and is a "pure" HTTP GET. Seaside sends back an html representation of the page in its new state. That page can be reloaded as much as you like with no side effects.


Basically, since Seaside is component based anyway, many people build a root component to contain header, footer, menus, etc, and then a component for body. You can then set the body component to any component you like and it'll render, no need for call. As Goran said, the component model is what makes Seaside rock so much, it's just like programming a desktop application, no fussing with state.


#call: is useful when you want to be able to switch a component in the page layout, in place, with zero effort [and] we are in direct control of the component's composition. #call: is a lower-level framework feature. For example, [in] this callback:

html anchor
callback: [counters atRandom call: WAMiniCalendar new];
with: 'Call component at random'.

we #call: one of the components. The effect of this is to show the mini calendar in place of one of the counters. We have not had to say anything else to achieve this, and get #answer support, back button support, etc.


In retrospect the main benefit, as I see it, of Seaside in Gjallar is the component model. The fact that I can construct the UI using separate components that can be used embedded inside each other and still render themselves totally oblivious of the environment and the request/response cycle.

The reason for this is of course the fact that a WAComponent is "persistent" in the user session and can hold all its state simply in instvars. So it erases the need for "inter request client side state management" using say URL params or hidden fields and so on.

All of which was followed by a general lament at the state of documentation for Seaside...