On 6 Jul 2007, at 1:23 am, Alaric Snell-Pym wrote:
I propose to create an egg called 'wings' to contain general utility functions for access .wings metadata files (there'll be other uses for the files in future, so I plan to create a generic framework), the definition of the wings-environment parameter and utility procedures for accessing same, utility and support functions for the data source API using the wings environment, then the aforementioned page argument handling tools.
Here's a progress report: - Wings environment works. You can bind stuff into the global environment, access bindings with (wings:get 'foo), and dynamically bind things with (wings:let (('foo 'bar)) (wings:get 'foo)). - Metadata file parsing works. (wings:call-with-metadata "/path/to/ file" thunk) will look for a file called "/path/to/file.wings" (the extension being configurable with a parameter). If it's not present, it just calls the thunk. But if it is present, it loads it and evals it within a quasiquote - so it's literal data, except you can use , to include bits of live Scheme code. It's treated as an alist of things to bind into the Wings environment during the dynamic scope of calling the thunk. If there's a entry in the alist called 'wrapper' then it's expected to be a closure, and is applied to the thunk. If not, the thunk is just invoked as-is. The "wrapper" key is meant as a catch-all to control the dynamic environment of the thunk, where parameters other than the wings environment can be changed, exceptions handled, etc. Now, the normal use of wings:call-with-metadata is to wrap Spiffy's handling of files, so we provide a function called wings:handler- wrap. If a Spiffy file extension handler is passed to this function, it returns a new one that wraps invocation of the original handler in a wings:call-with-metadata. So you can have .wings metadata handling added to your web-scheme, ssp, cgi, or whatever. - URL argument parsing is in progress. I've talked with Peter Bex about how to get Spiffy to support path info so I can have positional parameters in URLs, and while he's looking into that, I've pressed ahead with named query-string params. This is quite cool. I've written it so that it can handle nested compound argument types. Here's a sample argument declaration that demonstrates the atomic types: '((a "a" optional string) (b "b" symbol) (c "c" symbol a b c) (d "d" number) (e "e" integer) (f "f" string) (g "g" boolean) (h "h" boolean "yeah" "nope") ) The symbol at the head of each list is the name the argument will be bound to; the next element, the string, is the name to expect in the URL query string. The rest is typing information. If "optional" is not specified, then failing to provide this argument signals a condition that will, when I've written the higher-level driver, cause a 400 Bad Request to be sent back. If "optional" is specified, as with the "a" argument above, then omitting it causes #f to be bound to the name. Declaring something to be of type "string" just means that whatever the URL contains is passed back, unchanged. Type "symbol" on its own just passes it through string->symbol, but "symbol a b c" constrains it to be a symbol from the list (a b c). This is useful for things like the available options in a <select> form field. Anything outside of the list signals a condition, again. "number" causes a string->number, and if it returns #f, signals a condition. "integer" does the same as "number", but also requires the result to be an exact integer. This is useful for IDs of things in SQL databases, mainly. "boolean" alone interprets 1, t, yes, and y (case insensitive) as #t and 0, f, no, and n as #f, and signals a condition on anything else. Or you can write 'boolean "yeah" "nope"' to provide your own yes/no strings. Or you can provide lists of yes/no strings: 'boolean ("yeah" "sure") ("nope")'. But where we start to leave Rails in the dust is with the compound types. The simplest compound type is "set". Set just collects multiple instances of the argument in the query string and makes a list. If you declare an argument "x" to be of type "set symbol a b c", for example, then the parser will interpret a query string such as x=a&x=c as '(a c) - possibly in some other order. Set arguments are implicitly optional; no instances of an argument makes for an empty list. The next one I got working was "list", which looks for multiple arguments of the form "<argname>[<index>]" and collects them into a list, with the integer indices starting at 0. The list is long enough to fit the highest index, and any missing positions in the list are filled with #f. So if you defined an argument "x" as "list symbol" then the parser would see x[2]=foo&x[0]=bar as '(bar #f foo). But if you define an argument "x" as "list set symbol" then the parser will see x[2]=foo&x[0]=bar&x[2]=baz as '((bar) #f (foo baz)) - it's a list of sets, apart from the #f. And you can do things like "list list list integer", which will pick up query strings like "x[0][0][0]=1&...". Now, you can't nest a set inside a set - set can only wrap atomic types, since set has no ability to distinguish structure in the arguments it matches, unlike list. We also have alist, which generalises list somewhat; the indices are replaced with symbols. x[a]=1&x[b]=2 -> ((a . 1) (b . 2)). Lists and alists can nest as deeply as you like. And the best thing is, it seems to work. At least, the low level procedure that takes an argument type declaration and the alist of URL query string params as produced by the uri egg satisfactorily returns an alist binding argument name symbols to their parsed values. If you're interested, I've comitted what I have so far into svn (https://galinha.ucpel.tche.br/svn/chicken-eggs/wings/trunk) - no documentation yet, but the unit tests in tests/run.scm provide useful examples ;-) -- Alaric Snell-Pym Work: http://www.snell-systems.co.uk/ Play: http://www.snell-pym.org.uk/alaric/ Blog: http://www.snell-pym.org.uk/?author=4 _______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users