Seaside has inspired me to try to write a basic HTML/CGI based grid style widget. In Seaside, that widget is called WATableReport which is described here and provides column sorting as is available in most decent GUI widget sets. My web-fu is a little rusty. Last time I was writing web code was back in the dark ages pre-servlets and nice session managing frameworks using pure CGI. This may well be available somewhere already but what the heck, let’s get started…
First of all, we need a data-type for the table data. For now we will keep it simple and just have the column names and the data which will probably be a list of lists.
(define-struct table-data (columns data))
We will need to serialise the data so we can pass it to another page through the query string. I briefly toyed with the idea of having some custom format of lists of comma seperated values surrounded by square brackets. e.g.
[Task, Monday, Tuesday, Wednesday], [Cooking, 1hr, 1hr, 2hrs], ...
The parser tools supplied with PLT Scheme would make this fairly straight-forward. Even easier is using the read and print functions so we will go with that. I also want to be able to define a whole package of data for testing purposes and escaping every quote will be a pain so let me allow single quotes too. I had a look in the Scheme Cookbook for a simple way to transform characters within a string. string-map from srfi-13 offered a possibility, but we will almost certainly want something more powerful later so we might as well start with regexes.
(require (lib "pregexp.ss")) (define (string-encode s) (pregexp-replace* "'" s "\""))
Together with a function to convert strings to scheme objects we can provide a convenience function for converting manifest strings into our data.
(define (string->object s)
(read (open-input-string s)))
(define (string->data s)
(string->object (string-encode s)))
(define *data* #f)
(set! *data*
(string->data
"(('Task' 'Monday' 'Tuesday' 'Wednesday')
('Cooking' '1hr' '1hr' '2hrs'))"))
Next time we will look at encoding the data so we can pass it through the query string. At the moment, we will have a small problem with quotes and a few other characters…
(define (print-ln . args)
(for-each print args)
(newline))
(print-ln "<a href=\"ser.scm?data=" *data* "\">next page</a>")
> "<a href=\"ser.scm?data="(("Task" "Monday" "Tuesday" "Wednesday") ("Cooking" "1hr" "1hr" "2hrs"))"\">next page</a>"
Instead of a CGI program, have you considered doing this in the PLT Scheme Web server?
I’m sure at some point I’ll want to port this to a business-friendly language. If I wanted to use a special webserver I could stick with Seaside which has the functionality already available.
It is possible to use the PLT Scheme Web Server and migrate to having a mainstream server in front of it. I am also working on a mod_mzscheme to embed compiled Scheme servlets in apache.