[Seaside] Dynamic bindings...howto?

Avi Bryant avi at beta4.com
Sun Jun 13 23:48:34 CEST 2004


On Jun 12, 2004, at 10:27 PM, C. David Shaffer wrote:

> Avi Bryant wrote:
>
>> This reminds me - David, did you ever figure out the new 
>> configuration stuff?  If so, how about you write up a little 
>> tutorial? ;)
>>
>> On Jun 10, 2004, at 9:01 AM, Stephen Pair wrote:
>>
> No, I clicked around and made a real mess of things before giving up.  
> I don't understand the concept (maybe you could give me a one or two 
> sentence leg up here).  I'd be happy to write up whatever I figure 
> out.

Ok... here's some of the conceptual background.

A configuration is an instance of a concrete subclass of 
WAConfiguration. A configuration defines a set of attributes (which 
describe a value type, range of values, etc), a set of values for those 
attributes, and a set of ancestor configurations.  Depending on the 
class of configuration, these may all be specified programmatically, or 
may be set manually by the user.

Attribute values are treated similarly to method inheritance: if a 
configuration provides a value for a particular attribute, that value 
will override any values provided by its ancestors.  If it provides no 
value, the lookup continues up the ancestor chain.  There's a 
well-defined order (similar to that used in Dylan) when traversing 
complex multiple-inheritance trees.

There are three levels of configuration currently used by Seaside: 
SystemConfiguration, LocalConfiguration, and UserConfiguration.  The 
purpose of a SystemConfiguration is to define a particular set of 
attributes and global default values for them.  SystemConfigurations 
are specified purely programatically: they must implement #ancestors to 
return an array of ancestor configurations and #attributes to return an 
array of attribute values.  They may also implement methods 
corresponding to attribute names to provide default values (although 
they do not have to).  SystemConfigurations are singletons - each 
subclass has a unique instance, accessible through the #instance method 
on the class side.
WAAuthConfiguration is a good example of a system configuration: it 
provides the #login and #password attributes, and sets the #mainClass 
to default to WAAuthMain.  Adding WAAuthConfiguration as an ancestor of 
your application's configuration will immediately provide it with 
simple HTTP Basic Authentication.
The purpose of a LocalConfiguration is to allow a system administrator 
to override the defaults for a given SystemConfiguration on a site-wide 
basis.  Each LocalConfiguration instance has a single 
SystemOrganization instance as its ancestor, but has a dictionary of 
attribute values that can be modified at runtime to override the 
programmatic defaults from the SystemOrg.  Rather than directly using a 
SystemConfiguration instance as an ancestor to your app's 
configuration, it's better to use the corresponding LocalConfiguration 
so that changes to the defaults will properly affect you.  Thus, in the 
UI, it's the LocalConfiguration that will be shown as, eg, 
"WAAuthConfiguration", and is editable, whereas the SystemConfiguration 
will be shown as "WAAuthConfiguration defaults" and is immutable.
Finally, a UserConfiguration is completely user specified: like a 
LocalConfiguration, its values are specified at runtime, but unlike a 
LocalConfiguration, it can also have ancestors added and removed by the 
user.  Each application has an instance of UserConfiguration.  You can 
also add named user configurations that aren't associated with a 
particular application, that  can be reused (by adding them as 
ancestors) across several apps.

Combined with David's upcoming example, hopefully that will shed some 
light...

Cheers,
Avi



More information about the Seaside mailing list