Hi there,

others and I have been pushing the usage of local components in Five. As a result it looks like the CMF 2.1 will use the CA to look up its tools. Woohoo! (Kudos to Jens and all the others!)

There's one problem with all this which I admit I have failed to communicate better (certain key players know this for some time, but haven't spoken up either):

Using PersistentComponents() as the component registry (a.k.a. site manager) for local sites isn't enough. That's because it doesn't understand about containment hierarchies. Imagine this folder hierarchy:

/root_site/
+  cmf_site/
   +  somefolder/
   +  anotherfolder/
   +  sitefolder/
   +  +   stuff_in_here

"cmf_site" is obviously a site. Let's say "root_site" and "sitefolder" are also sites (yes, Zope3-style sites can be nested). That's not to say that sitefolder is another CMF Site, it's just a Zope3-style ISite (regular zope 2 folders can be sites in Zope 2.10).

You would expect component lookup at "stuff_in_here" to
* first lookup stuff in "sitefolder",
* then in "cmf_site",
* then in "root_site",
* and finally in the global registry

If you use PersistentComponents() this won't automatically happen!

Component registries have an __bases__ attribute which contains the next site manager in the in the lookup chain. Currently, we stub this out by simply putting the global registry in __bases__ and nothing else. The code that does this looks like that (this is from Jens's branch):

      components = PersistentComponents()
      components.__bases__ = (base,) # base is the global registry
      site.setSiteManager(components)

With such component registries in place at each "sitefolder", "cmf_site" and "root_site", component lookup will never cascade the way we intiutively would expect it from acquisition.


So, how do we fix this?

Obviously, the __bases__ attribute of site_folder's component registry must contain cmf_site's component registry and NOT the global one. cmf_site's registry in turn must refer to root_site's registry etc. Simple enough. It's really all about setting the right __bases__.

The tricky part is that this whole "linked list" of site managers needs to be updated when

* new sites are created somewhere in a hiearchy (e.g. root_folder used to be not a site, and now you turn it into one, then cmf_site's __bases__ should be updated to refer to the root_folder registry instead of the global one)

* sites get moved around, e.g. to places where you have a site higher in your parent hierarchy.

In Zope 3 already has code that deals with those things. It's a subclass of PersistentComponents called LocalSiteManager (zope.app.component.site). It figures __bases__ out itself based on the containment hierarchy (in Zope 3 that's __parent__).

LocalSiteManager is also a container (similar to a folder) so that local persistent components can be placed inside it instead of in the site object itself which normally contains only content objects. Usually the URL name of the site manager is ++etc++site, e.g. /cmf_site/++etc++site would be the site manager of cmf_site.

We need a LocalSiteManager implementation for Zope 2 (mostly because of the __bases__ thing, but perhaps also because we then have a designated place for local components instead of the portal root).

The Zope 2 version of LocalSiteManager should subclass PersistentComponents and then use Zope3's LocalSiteManager's approach to update __bases__ in the above mentioned cases. Zope 3's LocalSiteManager code contains some cruft that isn't needed in Zope 2. We really only need the __bases__ stuff (part of which is a subscriber for ObjectMovedEvent which needs to be adapted for Zope 2 as well). The most obvious difference is that the Zope 2 version of LocalSiteManager should use acquisition instead of __parent__ pointers to determine the containment hierarchy.

As a bonus, the Zope 2 LocalSiteManager could also mix in ObjectManager.


Since Five is feature-frozen and new stuff should be added in Python packages anyway, my suggestion is to put this thing into a five.localsitemanager package which would then be used by CMF 2.1, Plone 3, etc.. It could possibly be included into the Zope 2.11 release.

I'd like to avoid making a Five 1.6.


Philipp


--
http://worldcookery.com -- Professional Zope documentation and training
2nd edition of Web Component Development with Zope 3 is now shipping!

_______________________________________________
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests

Reply via email to