Re: Schema provider/CA lookup status

Martin Aspeli <[email protected]> Tue, 25 Jul 2006 01:58:49 +0100
Newsgroups gmane.comp.web.zope.plone.archetypes.devel
Message-ID <[email protected]>
Martin Aspeli wrote:

> I know Whit worked on this a while ago, but I'm unsure what state the 
> code is in. Basically, I have a use case now where I want to be able to 
> supply (most of) the schema to a content object with a (local) utility 
> so that third party products can plug in a schema without having to 
> re-invent the rest of my infrastructure.

I tried to experiment with this in 'company' last week, but
unfortunately, I didn't get very far.

Looking at whit's sole checkin on the whitmo-interface-by-schema branch,
the pattern is that BaseObject.Schema() returns ISchema(self) (i.e. self
adapted to ISchema), and you could register new adapters to provide
different schema's. The default implementation uses the .schema
attribute (which is really a class-attribute, though it's accessed as an
instance-attribute in the lookupSchema() method in adapters.py) as the
way to obtain a schema. Some tests are also updated to make sure the
registrations work.

I tried to do something similar to this, overriding Schema() in my own
content type to perform the adapter lookup. Unfortunately, it seems that
.schema is still used in several places in Archetypes.

I see examples of this in:

  - ArchetypeTool.registerType() (klass.schema)
  - BaseObject._updateSchema() (probably expected)
  - ClassGen.generateClass() (iterates over klass.schema.fields())
  - Extensions.utils.install_indexes() (iterates over klass.schema)
  - A bunch of the tests and examples :)

Now - the behaviour I see is even more bizarre. As a test, I did this to 
the Employee object:

     def Schema(self):
         """
         """
         return ImplicitAcquisitionWrapper(EmployeeSchema, self)

There is no 'schema' attribute set on the Employee class, although one 
will be inherited from BaseObject.

Employee has several fields, including 'id' (labeled 'user name', and 
changed to use a StringWidget instead of an IdWidget), 'password' (with 
mode='w', it's never read) and 'roles'. Employees are contained with 
'Department' objects. Note that 'Department' also has a field for 
'roles'. On the edit form, I don't see 'user name' (presumably due to 
the IdWidget still being in place), I don't see 'password' but I *do* 
see 'roles' (perhaps some acquisition is going on here from the parent 
Department, although the description on the widget is that from 
Employee, not the parent Department). Care to explain that one? :-(

Whit - did you ever have a chance to test your branch TTW, with an
example of a different schema? Am I just doing something wrong? I'm
confused by the fact that ArchetypeTool.getWidgetes() (which is what
base_edit.pt calls) uses instance.Schema(), suggesting it *should*
render my own schema, but it seems like it doesn't. I haven't been able
to dig deep enough into the field rendering code to make any more sense 
of this, but I'll try.

Fundamentally, though, it's not so strange the we have code relying on
klass.schema - it's an attribute of a class, not an instance after all!
If we wanted to restrict all usage to be just using Schema(), we'd need
an instance to call Schema() on each time, or we'd have to change
Schema() to be a classmethod (probably the latter).

The easiest solution for me right now would possibly be to make .schema
be a dynamic property - but still a class property. I'm not sure how you
do that - google suggests meta-classes and they make me scared. Perhaps
that is an option though - using a meta-class or hooking into the
constructor do the the dynamic lookup of the schema in the Component
Architecture there. Then, the Schema() method could do what it does now:
return ImplicitAcquisitionWrapper(self.schema, self).

There is probably a lot of edge cases here involving schemas becoming
persistent attributes of an object and _updateSchema() (the "update
schema" tab in archetype_tool), but I'm not sure my head could take much
thinking about those just now.

Martin


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV