domenica 22 luglio 2007

HttpView2's Canvas/Painter system

Most of my work on HV2 involves the creation of a new Canvas/Painter system. This is heavily inspired by Seaside's Canvas system, but has a couple of key differences.

Seaside's Canvas system is based around three classes.
The first, WACanvas, has the basic infrastructure for producing HTML tags.
The second, WAHtmlCanvas, is a WACanvas subclass that adds support for "static" HTML tags (such as <p>, <div>, etc.).
The last class is the main one you're going to use in Seaside: WARenderCanvas. This is a subclass of WAHtmlCanvas that adds support for the "dynamic" tags of HTML: forms, input fields etc, and is the most integrated with the other parts of Seaside.

I've pondered whether to reuse Seaside's Canvas system or not, and in the end I've decided against it: adapting it to HV2 would entail more work than creating a new system from scratch. Also, having another implementation of a Canvas system allows exploring other possible solutions to the problem of creating HTML from Smalltalk code.

HV2's Canvas/Painter system is similar to Seaside's Canvas one. There's a canvas class, currently named HVXHTMLCanvas, whose purpose is to produce HTML tags on a stream.

The user should use HVXHTMLCanvas directly, but should instead use an HVPainter instance. This painter class delegates most of the work to the canvas, but adds some high-level behavior like autonaming of form fields and automated retrieval of the values of the fields of a POST request.
Here's a snippet from a test application I'm building to test HV2's Canvas/Painter system:
painter form withFieldset: 
[summary := painter textField
label: 'Summary';
value: model summary.
location := painter painter textField
label: 'Location';
value: model location.
description := painter painter textField
label: 'Description';
value: model description.
button := painter submitButton value: 'Save'].
button ifPressed:
[model summary: summary value.
model location: location value.
model description: description value.
self redirectToDefault].

A nice change from HV2's old Builder system is that the form-autonaming feature of the new Canvas/Painter system may be easily overridden by the user: in the previous system, I could have used
painter textField
label: 'Summary';
name: 'summary';
value: model summary.

to create a text input field whose name would have been 'summary' instead of the name computed by HV2's Painter.

Working on HttpView2

As you may have noticed, in the past two weeks I've been silent. The reason for this is that I've been working on a couple of Smalltalk projects that have monopolized my attention.

One of these projects is HttpView2, also known as HV2. HV2 is the web framework behind SqueakMap. It's a nice little framework, and is a good complement to Seaside.

I'm actively involved in the development of the next version of HV2. In particular, I'm building a new Canvas/Painter system to replace HV2's current Builder system. I'll write another post with more details on the new canvas system.

I've also been exploring how to restructure HV2 to ease the creation of RESTful web services. I've a couple of ideas in mind: an easier access to the HTTP Response, more specialized View objects for single items and collections, and a few more that I still have to ponder.

The new HV2 version hasn't been released yet; you can grab my latest version of it from this (readonly) Monticello repository.

domenica 8 luglio 2007


Ieri con un paio di amici siamo andati a Birras, la prima festa delle birre artigianali sarde.

Pozzo Sartori

La festa si è svolta in alcuni dei locali del Pozzo Sartori della miniera di Montevecchio.

Erano presenti degli stand per degustare le birre dei sei produttori artigianali al momento presenti in Sardegna. In particolare ho apprezzato la Montevecchio chiara (nota un tempo anche come birra Dolomiti), la Dolmen chiara, la Janas Beer rossa e la Toccadibò della Barley. Non mi ha invece entusiasmato la chiara della Orteip’s Bir, che ho trovato troppo dolce.

Purtroppo al mio arrivo la degustazione guidata era già in corso, e non abbiamo voluto trattenerci fino all’inizio della degustazione successiva. In compenso siamo riusciti a seguire la dimostrazione pratica di homebrewing offerta dagli HomeBrewers Sardi.

giovedì 5 luglio 2007

Smalltalk & Simple Design

On the Extreme Programming mailing list, Ron Jeffries and others are explaining and defending why Smalltalk allows simpler designs than other languages.

Go read the whole thread, or start from this message.

martedì 3 luglio 2007

RESTful Web Services Example 2.15 - Yahoo! News Search w/ JSON

The final example from Chapter 2 of the RESTful Web Services book that I'll be converting to Squeak is another version of the Yahoo! Web Search, this time using JSON and, to spice things up a little, the news search service instead of the web search one.

In order to get this example to work, you'll have to install Squeak's JSON package, available from SqueakSource.

Here's the code for the example:
yahooNewsSearch: aString
| baseURI document term json |
"Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.
All rights reserved. Used with permission."
baseURI := ''.
term := aString encodeForHTTP.
json := Curl new getContentsUrl: baseURI , '?appid=restbook&output=json&query=' , term.
document := Json readFrom: json readStream.
((document at: #ResultSet) at: #Result) do:
[:element |
show: (element at: #Title) printString;

There isn't much to say about this example that hasn't been said for Example 2.1: the document returned from the #getContentsUrl: send is a JSON script that is fed to Squeak's JSON parser. The parser returns a nested structure of Dictionaries and Arrays that can be accessed with the standard at: message. The results are then printed to the Transcript, as usual.

The code for this method may be found in package RWS-gc.8 in the RWS repository.

This post concludes the series of examples from Chapter 3 of the RWS book. In the next posts (coming next week or so) I'll show examples from Chapter 3, including a complete implementation of a Squeak client for the Amazon S3 service.

lunedì 2 luglio 2007

The Bad Plus - Give

L’ultima entry nella mia collezione di CD è un album del 2004: Give dei Bad Plus.

The Bad Plus - Give

Mi piacerebbe farne una recensione, ma decisamente mi mancano le competenze per scrivere un articolo ben fatto sull’argomento. Mi limiterò quindi a suggerire alcune recensioni trovate in giro per la rete: la prima viene dal sito della BBC, le altre sono quelle presenti sulla pagina di Amazon del CD. Aggiungo anche una intervista pubblicata subito dopo l’uscita di quest’album ed un articolo/resoconto di un loro concerto a Roma nel 2005.

Personalmente, posso dire che l’album mi è piaciuto molto, e penso proprio che andrò al loro concerto a Cala Gonone a fine mese.

RESTful Web Services Example 2.4 - a client

Example 2.4 is a simple client that prints the most recent bookmarks added to an account.

The Squeak Smalltalk version is the following:
Chapter2>>deliciousRecent: username password: password
| deliciousURI xml document |
"Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.
All rights reserved. Used with permission."
deliciousURI := 'https://{1}:{2}'.
xml := Curl new getContentsUrl: (deliciousURI format: {username. password}).
document := XMLDOMParser parseDocumentFrom: xml readStream.
document posts post
do: [:each |
show: (each at: #description) , ': ' , (each at: #href);

If we compare it with the Ruby example in the book, there are a couple of differences.

The first one is the use of the Curl plugin, as anticipated in the previous post.
This forces us to insert username and password in the URI that we pass to #getContentsUrl:. In order to do this we use a relatively obscure feature of Squeak's String class: the #format: message. This message behaves like the C standard function printf().

Another difference is in the object returned by #getContentsUrl:. Instead of returning a Stream object, this message returns a string; but since XMLDOMParser requires a Stream object, we create one by sending #readStream to the string.

Once we have a DOM tree, we can select the post elements by sending
    document posts post

thus retrieving all the post elements. We then iterate over all these elements to print the description and href attributes.

The book provides two other Ruby versions of this example: one using the SAX parser, the other using the pull parser. I won't convert these two examples, since I don't think they're really significant in this context.

The code for this method is available on the RWS repository, in the RWS-gc.6 package.

In the next post, we'll see a new version of #yahooWebSearch: that uses JSON as the output format.

domenica 1 luglio 2007

Installing Pastell and the CurlPlugin

Before sailing forth in the high seas of REST, there's a couple of addition to do to the Squeak image: Pastell and the CurlPlugin.

Installing Pastell

Pastell is a package for Squeak that adds XPath-like navigability to an XML DOM tree. I'll be using it for all RESTful Web Services' Squeak examples.
In order to install Pastell, you'll have to:
  1. Open the Monticello Browser and add the Pastell repository. You'll fine the repository info on Pastell's SqueakSource page

  2. Load the package Pastell-gc.10 . This will install Pastell.

  3. From the RWS repository, update to RWS-gc.4 . Just select the package and click on the "Load" button. This will install a version of RWS modified to use Pastell.

Installing CurlPlugin

CurlPlugin is a plugin that allows access to libCurl's functionalities from a Squeak image. Currently only libCurl's "easy" interface is supported, but that's good enough for the next examples.

I've had trouble using the premade CurlPlugin, so I've prepared a new one for Squeak's Unix VM. Just grab and extract it in the same directory of your RWS image. After extraction, open the image and file in the file and you're done.

This version of the CurlPlugin has been compiled on Fedora 7 system against libCurl version 7.16.2 . If you have any trouble using this plugin or you're on a different platform, please leave a comment and I'll try to help you.

Once you have installed both Pastell and the CurlPlugin, don't forget to save your image.

Later this afternoon I'll publish another post detailing the next example: a client.