Archive for June, 2011
Smalltalk usage in a RAD Race
I recently participated in an internal RAD Race at my Employer QNH. A former collegue of mine from Nationaal Spaarfonds and I decided to participate using VA Smalltalk, Seaside and the component framework we call Wolluk.
But alas, we didn’t win…
We had some strong competition who used microsoft .net to generate the complete CRUD application and only filled need to fill in the blanks. Although we did finsih some nice wizard like UI’s for the RAD Race, we lacked in the autogenerated part, so we enden up second. not bad, but could be better.
So I started thinking where we went wrong. First of all: a RAD race is about functionality and not architecture. To auto generate 70% from the datamodel instantly adds points to your score.
Unfortunatly, My friend and I didn’t have enough experience with auto generated UI’s so we ended up coding everything our selves. Lessens learned…
I kwew of a framework called magritte which you can use to add meta descriptions to your classes. This week I will investigate this further and will check how I can integrate this with our wonderfull component framework called Wolluk to generate the whole application from the model.
Building an Envy Application Browser in Smalltalk
It’s bin a while, but here we go
A collegue of mine runs www.vastgoodies.com. A place where VA Smalltalk developers can share their open source projects and tools.
At home I use Pharo Smalltalk for my hobby projects, so stuff developed at work (like nice plugin wrappers for jqGrid and jsTree) all need to be ported manually to Pharo which is a pain to do.
So I came up with the idea to create a Monticello repository client in Pharo and extend vastgoodies.com to export Monticello Packages using some conventions which will only fit MY needs. I know there are many differences between the dialects, but if it can exchange my plugin wrappers and other cool seaside stuff using standard conventions my goals are achieved
To get to know Envy, i wanted to start with something simple. The Browse button for applications was showing a place holder for a application browser so I decided to start with that.
The basic layout for the application browser consists of 4 columns with a 2 tabs at the bottom.
The first columns shows al the applications in the configuration map, the second shows the classes in the selected application, the third lists the categories in the selected class and enables the user to select the instance or class side of the categories.
And the fourth column shows the methods in that protocol. Multiple protocols can be selected and it will list all methods in these protocols.
The first tab shows the Class definition and the second the method source.
Once you click on a method, the source code is shown with a Syntax Hihglighter using the Smalltalk Brush created by Daan van Berkel.
Some more details….
A3aan already wrote a Envy Library Accessor which I extended to retrieve the extra data from the Envy repository. All operations on the Envy Repository are mutally exclusive, which means that no process can access the repository at the same time. This support was already built in, so I just used that
EnvySeasideLibraryAccessor>>applicationsFor: aConfigurationMapOrNil
(aConfigurationMapOrNil isNil) ifTrue: [ ^#() ]. ^self do: [ aConfigurationMapOrNil shadowApplications ] EnvySeasideLibraryAccessor>>do: aBlock "No problem to call this nested (from one process). Nesting is faster then repeated call anyway." ^[Mutex critical: aBlock] ifCurtailed: [EmLibrary startUp]
The applicationsFor: returns a collection of EmShadowApplication instances where I would only like to print the signature in the list.
EnvySeasideConfigurationMapVersionBrowserComponent>>renderAppColumnOn: html
(html select)
size: 20;
on: #app of: self;
list: self applications;
labels: [:each | each signature];
onChange: (html jQuery ajax serializeThisWithHidden script:
[:s |
category := nil.
method := nil.
className := nil.
self renderRerenderClassScriptOn: s.
self renderRerenderCategoryScriptOn: s.
self renderRerenderMethodScriptOn: s.
self renderRerenderContentsScriptOn: s])
When the onChange event fires, I reset the instance variables category, method and class name and rerender the columns and content pane on the bottom.
EnvySeasideConfigurationMapVersionBrowserComponent>>renderRerenderClassScriptOn: s s << (s jQuery id: #classColumn) html: [:h | self renderClassColumnOn: h]
Interaction with the other select lists is done in pretty the same way.
Getting the source code is also a very simple operation:
EnvySeasideLibraryAccessor>>sourceCodeFor: aSelector in: aShadowClassInstance ^self do: [aShadowClassInstance sourceCodeAt: aSelector ifAbsent: ['']]
Where do these shiny colors come from?
Using the syntax highlighter supplied described above works pretty well if the source code content is already in the DOM before you call the syntax highlighter.
But if the source code is loaded using a ajax call, the syntax highligher does not know it needs to redraw the preformatted area.
Luckily, the syntax highlighter can be invoked to restyle the preformatted area pretty easily.
EnvySeasideLibraryAccessor>>renderRerenderContentsScriptOn: s s << (s jQuery id: #classDef) html: [:h | self renderClassDefOn: h]. s << (s jQuery id: #code) html: [:h | self renderPreformattedCodeOn: h]. s << (JSStream on: 'SyntaxHighlighter.highlight();'). s << (s jQuery id: #contents) tabs select: 1
I could write a wrapper around the SyntaxHighlighter javascript library, but this works as well
So that’s it! Pretty easy exercise to get an application browser into vastgoodies.

