[Seaside] Javascript rendering and dynamically bound variables

Mariano Montone marianomontone at gmail.com
Tue May 26 15:46:48 UTC 2009

     I'm developing a GoogleMaps component and have to decide how to
implement the Javascript generation.

The thing is I'm using a dynamically bound variable to hold the stream
to render the javascript on and I'm not sure that's considered good
style in Seaside.

For those who are not familiar with dynamically bound variables, here
are some documents that explain them briefly:

In seaside they are used to access the current session (se WACurrentSession).
Besides, they are a feature extensively used in other languages like Common
Lisp (and with the same purpose I am considering using them for).

I need to generate Javascript and keep some bindings from the Smalltalk side
of the generated Javascript variables. So, for example, this is what I have

WADraggableMarkerMap>>renderContentOn: html
	self map
		center: 45.5267 @ -122.8390 zoom: 11;
	marker := (GMarker at: 45.5267 @ -122.8390)
                              draggable: true;
		              onDrag: ( html gmrequest callback: [:latlng | marker
color: GColor blue ]).
	self map addOverlay: marker.

In the code above, I'm rendering map and then create a marker and add
it to the map. Both the GMarker instantiation and the attributes
settings must generate javascript.

The generated javascript is the following:

var map1=new google.maps.Map2(document.getElementById("id3"),mapOptions);
map1.setCenter(new GLatLng(45.5267,-122.839), 11);
window.map1_marker1 = new GMarker(new GLatLng(45.5267,-122.839), {
draggable : true });
GEvent.addListener(window.map1_marker1, "drag", function(location){
          new Ajax.Request('http://localhost:8080/seaside/GM+maps',{'parameters':

Note that the marker variable in the Smalltalk code is an instance
variable and holds its javascript variable name (window.map1_marker1).
That lets me refer to the marker added to the map later. For example,
in the code above, when the user drags the marker, the callback
setting the marker's color is called. That callback generates
javascript to be executed as a response to the dragging. In
particular, the following javascript is executed:

window.map1_marker1.setColor(GColor blue);

To achieve the same giving up to dynamic variables and sticking to
Seaside brushes would require my protocol to change to something
similar to this:

marker := (GMarker at: 45.5267 @ -122.8390)
                              draggable: true;
		              onDrag: ( html gmrequest callback: [:latlng : renderer |
                                   marker color: GColor blue.
                                   marker renderOn: renderer ]).

That is to say, I have to explicitely render each of my variables to
the lexically scoped renderer. Besides, there's a renderer variable
apart from the arguments that are interesting to the callback (latlng
in this case, that holds the position the marker was dragged to).

As for the implementation with dynamic variables, the javascript is
being rendered on a dynamically bound stream, that is set in a Seaside

WAGMapComponentDecoration>>renderContentOn: html

	brush := html googleMap
			class: 'googleMap';
			style: self component mapStyle;
	self component brush: brush.
	WACurrentJSStream use: brush stream
				       during: [ self component renderContentOn: html ]

To sum up, on the one hand, this approach is not the way Seaside
commonly renders
Javascript or HTML. On the other hand, my opinion is that using
brushes spoils the protocol at a certain extent, but I would like to
hear your opinions here.

What do you think? Can you come up with other alternatives? Which approach
do you prefer over the other and why?

Sorry for the long post, but couldn't find a way of explaining my
problem more briefly.

Thank you very much!


More information about the seaside mailing list