[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