explicit/controlled/filtered acquisition for Folders?
After dealing with using Zope for websites for two years, I've come to the point where I think implicit acquisition should be an optional feature when retrieving web content that looks less like objects and more like folders of documents. Implicit acquisition means that when you ask for "/folder1/folder2/folder3/mydoc.html", you might well get /mydoc.html . That might be useful in parts of the object world, but for folders and documents it is almost never right. Yes, if all your links are correct, that won't happen, but users don't always have links correct. Furthermore, the "infinite recursion" problem can easily happen when search engines follow self-referential links. It's possible to work around the problems by using "aq_explicit" and "absolute_url", but those strategies are cumbersome as they represent Zope-specific tailoring. Acquisition isn't limited just to implicit acquisition, though. Has anyone put any thought or work into creating an ObjectManager and Folder that allowed explicit, controlled or filtered acquisition? * ExplicitAcquisitionFolders would act as "limits" or "stops" that isolate different zope application trees from each other. * Controlled or filtered acquisition folders could have a property that declares which methods would be acquired, much like "import" statements in python. Either option would let developers choose, understand, and limit what they were acquiring from outside the local context. I think both document- and object-like Zope sites would benefit. Choice of mechanism is good. I've looked into the required changes some, but the ObjectManager and Folder classes know about each other in a way that doesn't seem completely straightforward to an outsider. I don't think I know enough to write the new classes, especially without a wholesale copy of the existing classes. To those in the know, how hard would it be to do, and what issues would be involved? Thanks. Michael Halle mhalle@media.mit.edu
Michael Halle writes:
* ExplicitAcquisitionFolders would act as "limits" or "stops" that isolate different zope application trees from each other.
* Controlled or filtered acquisition folders could have a property that declares which methods would be acquired, much like "import" statements in python. The acquisition machinery supports all this. Have a look at the acquisition documentation in "lib/Components/ExtensionClass/doc/Acquisition.stx".
What you probably need: derive a new ObjectManager from Acquisition.Explicit and the current ObjectManager. provide an interface to manage the attributes that should be acquired implicitly. Dieter
Dieter Maurer wrote:
What you probably need:
derive a new ObjectManager from Acquisition.Explicit and the current ObjectManager.
provide an interface to manage the attributes that should be acquired implicitly.
Well, I had a go at this, but not quite in the way you describe. I subclassed Folder and overrode __getattr_ with: def __getattr__(self, name, higher_getattr=higher_getattr): if self.__enabled: if name in self.__names: return higher_getattr(self, name) return higher_getattr(higher_getattr(self,'aq_explicit'), name) return higher_getattr(self, name) where higher_getattr comes from: try: higher_getattr = Folder.inheritedAttribute('__getattr__') except: def higher_getattr(self, name): raise AttributeError, name Except, using self.aq_explicit instead of self has no effect, the name is still acquired normally :-( What's going on? This feels like the same bug in aq_explicit that I posted here and in the collector to no response :-S cheers, Chris
Chris Withers writes:
Dieter Maurer wrote:
What you probably need:
derive a new ObjectManager from Acquisition.Explicit and the current ObjectManager.
provide an interface to manage the attributes that should be acquired implicitly.
Well, I had a go at this, but not quite in the way you describe.
I subclassed Folder and overrode __getattr_ with: This does not work because Python calls "__getattr__" only, if it can not find the attribute through "normal" means. Due to the implementation of "Acquisition", acquired attributes are found by "normal" means bypassing "__getattr__".
You may be successful, if you override "__of__". It is this method that (usually) builds the acquisition wrapper. You can try to build an explicit rather than implicit acquisition wrapper. The easiest way, of course, is to derive the class from "Acquisition.Explicit" with higher priority (more to the left) than from "Acquisition.Implicit". Dieter
Dieter Maurer wrote:
Chris Withers writes:
Dieter Maurer wrote:
What you probably need:
derive a new ObjectManager from Acquisition.Explicit and the current ObjectManager.
provide an interface to manage the attributes that should be acquired implicitly.
Well, I had a go at this, but not quite in the way you describe.
I subclassed Folder and overrode __getattr_ with: This does not work because Python calls "__getattr__" only, if it can not find the attribute through "normal" means. Due to the implementation of "Acquisition", acquired attributes are found by "normal" means bypassing "__getattr__".
Ah, that makes sense :-)
You may be successful, if you override "__of__". It is this method that (usually) builds the acquisition wrapper.
When does it not build the wrapper?
You can try to build an explicit rather than implicit acquisition wrapper.
Yeah, I'll give it a go, once the problems below have been worked out...
The easiest way, of course, is to derive the class from "Acquisition.Explicit" with higher priority (more to the left) than from "Acquisition.Implicit".
Hmmm... then maybe use the acquire() method to get hold of names that can be acquired, in the __getattr__ method? There is a more fundamental problem here though; If you limit acquisition to a specified list of names, what do you do about all the stuff Zope normally silently acquires, like the security context, the REQUEST, etc? It would be great if you could make it work along the lines of "acquire all the Zope internal stuff, but beyond that, only acquire if the name is in this list". But how would we define "all the Zope internal stuff" and how would we implement the logic? Hurm... this sounds like a problem of Fultonesque proportions :-S cheers, Chris
Chris Withers writes:
Dieter Maurer wrote:
You may be successful, if you override "__of__". It is this method that (usually) builds the acquisition wrapper.
When does it not build the wrapper? If it is not the "__of__" defined by "Acquisition.{Im,Ex}plicit", it may not build acquisition wrappers. E.g. the "__of__" of "ComputedAttribute" does not.
The easiest way, of course, is to derive the class from "Acquisition.Explicit" with higher priority (more to the left) than from "Acquisition.Implicit".
Hmmm... then maybe use the acquire() method to get hold of names that can be acquired, in the __getattr__ method? Read the "Acquisition" documentation:
With explicit acquisition, you can declare that some attributes should be acquired implicitly. Of course, you can do it in "__getattr__", too.
There is a more fundamental problem here though; If you limit acquisition to a specified list of names, what do you do about all the stuff Zope normally silently acquires, like the security context, the REQUEST, etc? I expect, that the security context is explicitly acquired (not sure).
For "REQUEST" and some essential other objects, you can declare them to be implicitly acquired.
It would be great if you could make it work along the lines of "acquire all the Zope internal stuff, but beyond that, only acquire if the name is in this list". But how would we define "all the Zope internal stuff" and how would we implement the logic? The first question may have some surprises. The second should not be too difficult.
Hurm... this sounds like a problem of Fultonesque proportions :-S Maybe, we wait a bit. As I heard, DC is thinking about making acquisition explicit rathen than implicit.
Dieter
participants (3)
-
Chris Withers -
Dieter Maurer -
Michael Halle