I have a Page Template and Python Script that are working fairly well together to generate a navigational menu on my site, and now I want to make them part of a product. I have tried this: class CMS(Folder): # ... # old "menu" Page Template copied to www/menu.zpt file security.declareProtected('View', 'menu') menu = PageTemplateFile('www/menu', globals()) menu._owner = None security.declareProtected('View', 'menu_items') def menu_items(self, levels=2, REQUEST=None): context = self._getContext # body of old "menu_items" Python Script copied here def _getContext(self): while 1: self = self.aq_parent if not getattr(self, '_is_wrapperish', None): return self I cannot seem to find the way to get the bindings a Python Script has, particularly the context binding. As you can see, I tried grabbing the _getContext method from Script, but it gives me the root Zope object, instead of the object that is being requested and having menu called on it from the web. What am I doing wrong?
John K. Hohm writes:
I have a Page Template and Python Script that are working fairly well together to generate a navigational menu on my site, and now I want to make them part of a product. I have tried this: The "context" equivalent in a Python product's method is usually "self.aq_parent"; the "container" equivalent "self.aq_inner.aq_parent".
Dieter
Quoting Dieter Maurer <dieter@handshake.de>:
John K. Hohm writes:
I have a Page Template and Python Script that are working fairly well together to generate a navigational menu on my site, and now I want to make them part of a product. I have tried this:
The "context" equivalent in a Python product's method is usually "self.aq_parent"; the "container" equivalent "self.aq_inner.aq_parent".
I expected you to be right, so I tried a simple method like this: security.declarePublic('foo') def foo(self): """Test method""" return self.aq_parent.absolute_url() When called through the web, it displays the URL for the parent of the instance that defines foo, not the object on which I'm calling the method. Aargh!
John K. Hohm writes:
Quoting Dieter Maurer <dieter@handshake.de>:
John K. Hohm writes:
I have a Page Template and Python Script that are working fairly well together to generate a navigational menu on my site, and now I want to make them part of a product. I have tried this:
The "context" equivalent in a Python product's method is usually "self.aq_parent"; the "container" equivalent "self.aq_inner.aq_parent".
I expected you to be right, so I tried a simple method like this:
security.declarePublic('foo') def foo(self): """Test method""" return self.aq_parent.absolute_url()
When called through the web, it displays the URL for the parent of the instance that defines foo, not the object on which I'm calling the method. Aargh! You are right and I need to be more careful!
Accessing a method can restrict acquisition information. The precise rules are difficult to grasp, but it is easy to present a case where you are unable to obtain the true context: An acquisition wrapper has two components "self" and "parent". When you look up an attribute (such as a method) it is first looked up in "self" and, if this lookup fails, it is looked up in "parent". When the lookup in "self" fails, the method's "self" will not have the full acquisition context and ".aq_parent" will not give to true context. Otherwise, it might but need not be the case. Dieter
On Wed, Dec 04, 2002 at 10:21:03PM +0100, Dieter Maurer wrote:
John K. Hohm writes:
Quoting Dieter Maurer <dieter@handshake.de>:
John K. Hohm writes:
I have a Page Template and Python Script that are working fairly well together to generate a navigational menu on my site, and now I want to make them part of a product. I have tried this:
The "context" equivalent in a Python product's method is usually "self.aq_parent"; the "container" equivalent "self.aq_inner.aq_parent".
I expected you to be right, so I tried a simple method like this:
security.declarePublic('foo') def foo(self): """Test method""" return self.aq_parent.absolute_url()
When called through the web, it displays the URL for the parent of the instance that defines foo, not the object on which I'm calling the method. Aargh! You are right and I need to be more careful!
Accessing a method can restrict acquisition information.
The precise rules are difficult to grasp, but it is easy to present a case where you are unable to obtain the true context:
An acquisition wrapper has two components "self" and "parent". When you look up an attribute (such as a method) it is first looked up in "self" and, if this lookup fails, it is looked up in "parent".
When the lookup in "self" fails, the method's "self" will not have the full acquisition context and ".aq_parent" will not give to true context. Otherwise, it might but need not be the case.
You seem to be saying that luck is required for a method to get proper acquisition information. How can this be? Aren't methods acquired all over the place? What alternatives to methods exist for defining objects that can be acquired?
Am 05.12.2002, 05:34 Uhr schrab John Hohm <jhohm@acm.org>:
You seem to be saying that luck is required for a method to get proper acquisition information. How can this be? Aren't methods acquired all over the place? What alternatives to methods exist for defining objects that can be acquired?
This is far from efficient, but if you're really desperate you can try the following approach (untested code, may contain errors): myurl=self.absolute_url() mypath=myurl[len(Request.get("URL0"))+1:] thisisme=self.restrictedTraverse(mypath) Jo. -- Internetmanufaktur Jo Meder ---------------------- Berlin, Germany http://www.meder.de/ ------------------- fon: ++49-30-417 17 63 33 Kollwitzstr. 75 ------------------------ fax: ++49-30-417 17 63 45 10435 Berlin --------------------------- mob: ++49-170- 2 98 89 97 Public GnuPG-Key ---------- http://www.meder.de/keys/jo-pubkey.txt
Am 05.12.2002, 08:32 Uhr schrab Jo Meder <jo@meder.de>: I hate to follow up to myself, but here you go: first error found. Sorry.
myurl=self.absolute_url() mypath=myurl[len(Request.get("URL0"))+1:]
Should be mypath=myurl[len(Request.get("BASE0"))+1:]
thisisme=self.restrictedTraverse(mypath)
Sorry again. Jo. -- Internetmanufaktur Jo Meder ---------------------- Berlin, Germany http://www.meder.de/ ------------------- fon: ++49-30-417 17 63 33 Kollwitzstr. 75 ------------------------ fax: ++49-30-417 17 63 45 10435 Berlin --------------------------- mob: ++49-170- 2 98 89 97 Public GnuPG-Key ---------- http://www.meder.de/keys/jo-pubkey.txt
John Hohm writes:
.... You seem to be saying that luck is required for a method to get proper acquisition information. That depends on what you mean with "proper".
Apparently, the acquisition information passed into a method is proper for most applications (as there are very few complaints). When I worked on my "References" product <http://www.dieter.handshake.de/pyprojects/zope> I tried to pass full acquisition context into a method. This resulted in a very expensive lookup process. However, it well possible (even probable) that this was caused by an error in my implementation. I now emulate the context passing of "Acquisition".
How can this be? Aren't methods acquired all over the place? Apparently, they usually do not need complete acquisition context when they are acquired.
What alternatives to methods exist for defining objects that can be acquired? You use an object (more precisely "ExtensionClass" instance), acquire it (it gets full acquisition context) and call its methods (the self passed in has then full acquisition context).
Dieter
participants (4)
-
Dieter Maurer -
Jo Meder -
John Hohm -
John K. Hohm