What and Why

What is the difference between component (WAComponent) and task (WATask)?

Both of them are reusable, embeddable, callable pieces of user interface. A component has state (instance variables), behavior (it may change its state, and it may also choose to display other components with #call:), and appearance (it renders HTML). A Task has only the first two - it doesn’t render any HTML directly, but only through the components it calls. This is useful when what you want to encapsulate/embed/call is purely a process (show this component, then this one, then this one). The key method for WATask is #go - as soon as a task is displayed, this method will get invoked, and will presumably #call: other components.

What is canvas API, what is the motivation?

See original post in the mailinglist.

The basic problem that Canvas is trying to solve is that of combinatorial explosion in the protocol of WARenderCanvas. Consider something like a text input. The original, basic method for rendering a text input was #textInputWithValue:callback:

html textInputWithValue: person name callback: [:v | person name: v]

But there’s also a variation using the ...On:of: pattern:

html textInputOn: #name of: person

And a variation with a liveUpdate callback:

textInputWithValue: person name
callback: [:v | person name: v]
liveCallback: [:r :v | ...].

Now what if we want to use both of these variations at once? Do we also need #textInputOn:of:liveCallback:? What about #passwordInputOn:of:liveCallback:? And so on. It’s relatively easy to add new convenience methods, but it’s a huge pain to combine them, even when (as in this case) they’re totally orthogonal.

The Canvas renderer is just a slight change to the API style that makes this kind of combination much easier. It divides what would have been a single method on HtmlRenderer into three steps: first, you tell the canvas what kind of "brush" (tag, usually) you want to use. For example, the method #textInput will return a new instance of WATextInputTag. Then, you use protocol specific to that brush to configure it: for example, you might send it some combination of #value:, #callback:, #on:of:, etc. You almost never need to use temps when doing this, but can do it with cascades instead:

html textInput
value: person name;
callback: [:v | person name: v].


html textInput on: #name of: person

The third step is to render any contents or children (if any) of this tag. You do this by passing some renderable (often a block) to the method #with:. A text input wouldn’t have any, but consider something like a table:

html tableRow
rowSpan: 3;
[html tableData with: [html bold with: person name].
(html tableData) colSpan: 2; with: [....]]

Note that instead of using #attributeAt:put: before the element, as in HtmlRenderer, attributes are set as part of the configuration step - and so classes like WATableRow can implement convenience methods for common attributes like #rowSpan: as needed.

If no configuration is needed, you can combine the first and third steps by using a keyword message instead of a unary message to specify the brush type, which is more compact:

html tableRow
rowSpan: 3;
[html tableData: [html bold: person name].
html tableData ....]

This style of API still allows streaming - the HTML for the open tag is generated as soon as #with: is sent. If #with: is never sent, it’s triggered automatically (with an empty block) whenever the next tag is started. That means #with: does have to be the last thing you send, any configuration done afterwards will have no effect.

Sometimes a temp is handy:

myDiv := html div.
self useSpecialId ifTrue: [myDiv id: 'specialId'].
myDiv with: [html text: '....']

But bear in mind that these are basically temporary objects - it won’t do you any good to stash them in an ivar and try to use them later, for example.

The Canvas implementation in present since 2.6a versions. It’s the default in the 2.8 versions.

What is the new header API, what is the motivation?

See original post in the mailing list


Now that both Seaside 2.7a1 and 2.6b1 have the "new" header API i think its time to write something short about it so people don’t have to ask.

The old header API was suffering from the same problems as the old renderer API. Just to add an stylesheet with media and title you had to copy and paste about 4 methods. Addional 4 for alternate stylesheets. If you wanted a new conditional import you needed to copy and paste a 3 LOC method. And so on. So we followed the same path like the Canvas API and made use of cascades.

The new API offers four base methods to create elements

  • #base, for base elements
  • #if, for conditional imports
  • #link, for link elements
  • #meta, for meta elements
  • #script, for script elements

Most of the time will want to use one of these two convenience methods:

  • #javascript, for JavaScripts
  • #stylesheet, for CSS stylesheets

See the classes WABaseElement, WAConditionalComment, WALinkElement, WAMetaElement and WAScriptElement for details


aRoot stylesheet
url: 'styles/blue.css'.
aRoot stylesheet
document: 'a { color:red; }'.
aRoot javascript
url: 'scripts/scriptaculous.css'.
aRoot if lessThan; ie7; do: [
aRoot javascripts
url: 'iehacks.js'].

Contrary to the Canvas renderer API the new header API in the background still used the old implementation. So you will have to implement no methods like #rendererClass.

If you use the old API on Seaside 2.7a1 and have the development toolbar on you will get a warning pointing to where you use the old API. These methods include the code that you should replace yours with.


What is source code structure of Seaside in Cincom Smalltalk?

For many different reasons Seaside is broken into a complex and cumbersome bundle/package structure.

At a higher level, Seaside is broken into three bundles :

  • Seaside-VW
  • Seaside
  • Seaside-WekToolKit

that must be loaded in the exact same order shown above.

The first bundle Seaside-VW contains pre-requisites and is actually preparing Cincom Smalltalk for Seaside. This bundle also has a complex structure. See below for further details.

The second bundle Seaside contains the original Seaside code unaltered from Squeak. The structure of this bundle is derived from the corresponding Seaside Monticello package. No further details are provided here.

The third bundle Seaside-WebToolKit contains the integration code for running Seaside inside the WebToolkit framework, along with some patches to both Seaside and WebToolkit. See below for more information.

Note: There exists also a Seaside-Swazoo bundle that contains the integration code for running Seaside inside the Swazoo framework. This is described below in more details.

One-click loading: Loading Seaside means loading the three bundles in the order above, making sure the bundle versions are compatible. However to provide one-click loading, there is another bundle named SeasideForWebToolkit that contains a script that loads the three bundles programmatically.

The contents of the Seaside-VW bundle are:

  • Squeak-Chronos - This bundle adds Squeak compatibility to the base Cincom Smalltalk image and includes a full port of the Squeak Chronology classes providing classes like Duration, Year, Month, Week, etc. This bundle contains all the known Squeak compatibility extensions that could be found in the repository. It can be used for any project that needs Squeak compatibility.
  • Seaside-Store-Patch - This package includes a patch to Store to allow loading of packages that include a $/ in their name. Note : Those names were given a few years ago, renaming those packages would be a risky task.
  • Seaside - This package defines the Seaside namespace. The definition of the Seaside namespace was originally done in the Seaside bundle (see below). However it had to be defined earlier so that the Squeak versions of the Date, Time, TimeZone and Color classes could be made available to the Seaside namespace.
  • Seaside/VW Support - This package includes extensions to the Cincom Smalltalk classes that are needed by Seaside. It also includes the SeasidePlatformSupport class that is expected by Seaside. This class includes many utilities on the class side that are used to create the Seaside ports. Method #portSource answers a constant that represents the original source of the Seaside Monticello package.

The contents of the Seaside-WebToolKit bundle are:

  • Seaside/Patches - This package includes patches to the Seaside code in the form of extensions and overrides. These patches are there to fix issues that are still not fixed in the Seaside Squeak source.
  • WebToolkit/Patches - This package includes patches to the WebToolkit code in the form of extensions and overrides. These patches are there to fix issues that are still not fixed in the WebToolkit product.
  • Seaside/WebToolkit - This package contains the actual integration between Seaside and WebToolkit, i.e. pieces of software that are specific to WebToolkit. The most important item is the SeasideServlet class. Of interest is the AAADocumentation class that provides guidelines on how to set things up and a few methods that are used to build the sample HTTP server and the sample web site.

The contents of the Seaside-Swazoo bundle are:

  • Seaside/GIF - This package includes some classes from VisualWave that are needed to support GIF images, since Swazoo does not have any support for GIF.
  • Swazoo/Patches - This package includes patches to the Swazoo code in form of extensions and overrides. It adds explicit support for cookies that is missing in Swazoo.
  • Seaside/Patches - This package is the same as the one included in the Seaside-WebToolKit. See above.
  • Seaside/Swazoo - This package contains the actual integration between Swazoo and WebToolkit, i.e. pieces of software that are specific to Swazoo. The most important item is the SeasideResource class. Of interest is the AAADocumentation class that provides guidelines on how to set things up and a few methods that are use to build the sample Swazoo server.

What is stored in the Seaside Sesssion Cookie?

The Seaside session cookie stores a number that allows the sever to identify your browsing session. It does not store any information about you. You can delete it, when you close your browsing session.