Yup, This looks good, as did your earlier post. However, it raises a question :( Something like a ZCatalog or a Squishdot Site (which I have a passing interest in ;-) are both folderish. However, their __call__ method does something quite different: it returns the results of searching the catalog (I think this is the ZSearchable Interface, correct me if I'm wrong ;-) I guess what's bothering me is why __call__ has this dual role and how the rendering process manages to correctly render index_html even on a Squishdot object which is actually callable? Hmm... I guess the implication of this is that a normal folder will never render itself to avoid confusion over the ZSearch interface and so if I want this behaviour I'll have to roll-my-own folder which inherits from ZCallable. Any ideas/comments? Chris PS: Shane: what's the difference between ZCallable and the ZRenderable base class that Maik Roeder mentioned on zope@zope.org a few days back? On Fri, 14 Jul 2000, Steve Alexander wrote:
Chris,
Related to your question earlier, have you seen Shane Hathaways' recent checkin into PTK?
"Added the ZCallable product, which is a very simple base class that makes it possible to call an class instance directly."
--------
from ExtensionClass import Base
class ZCallable (Base): def __call__(self, *args, **kw): '''Calls index_html, if it exists, to render this object. ''' base = getattr(self, 'aq_base', self) if hasattr(base, 'index_html'): v = self.index_html args = (self,) + tuple(args[1:]) return apply(v, args, kw) else: raise AttributeError, 'index_html'
def initialize(context): context.registerBaseClass(ZCallable)
--------
-- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
Chris Withers wrote:
Yup,
This looks good, as did your earlier post. However, it raises a question :(
Something like a ZCatalog or a Squishdot Site (which I have a passing interest in ;-) are both folderish. However, their __call__ method does something quite different: it returns the results of searching the catalog (I think this is the ZSearchable Interface, correct me if I'm wrong ;-)
I guess what's bothering me is why __call__ has this dual role and how the rendering process manages to correctly render index_html even on a Squishdot object which is actually callable?
I just looked over the source to ZCatalog. I'm pretty sure that __call__ has nothing to do with any index_html you might add to a catalog. The __call__ method is what gets invoked when you call the method, either through the magic of <dtml-var Catalog> or with <dtml-var "Catalog(client, namespace, args*)">. If Catalog has an index_html, or acquires one, then that is what gets rendered when you go to the URL http://mysite.tld/foo/Catalog -- actually, it seems that the effective URL is http://mysite.tld/foo/Catalog/index_html. Therefore, if you don't have an index_html, it gets acquired. This behaviour is set in lib/python/ZPublisher/BaseRequest.py, method traverse(), line 257. (I'm using 2.2 final). # Set the default method if method=='GET' or method=='POST': method='index_html' else: baseflag=1 and later on, at line 300. elif (method and hasattr(object,method) and entry_name != method and getattr(object, method) is not None): request._hacked_path=1 entry_name = method So, if you're getting or posting, you effectively get "index_html" appended to your URL. This way of doing things allows individual classes to define protocol handlers for other protocols they wish to support -- such as the PUT() method in DTMLMethod.py. Thus, index_html() is the protocol handler for GET and POST. This mechanism is pretty much separate from the __call__ mechanism. In conclusion, I can't see any disadvantage to making Folder callable as I suggested in a previous message. It doesn't appear to break anything :-)
Hmm... I guess the implication of this is that a normal folder will never render itself to avoid confusion over the ZSearch interface and so if I want this behaviour I'll have to roll-my-own folder which inherits from ZCallable.
I'm not sure your paragraph above makes sense in light of what I've said above.
PS: Shane: what's the difference between ZCallable and the ZRenderable base class that Maik Roeder mentioned on zope@zope.org a few days back?
IIRC, ZRenderable lets you choose what method you want __call__ to forward to, whereas ZCallable always chooses the method index_html, if it exists. -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
Steve Alexander wrote:
The __call__ method is what gets invoked when you call the method, either through the magic of <dtml-var Catalog> or with <dtml-var "Catalog(client, namespace, args*)">.
Now you see, this is what confuses me... <dtml-var dtml_method> renders that method, implying in my mind that __call__ should render stuff adn return it. However, then with ZSearchable stuff, <dtml-var catalog> returns a list of all the objects in the catalog, or does a search if you poke it right. In my mind, __call__ is a bit ambiguous right now. I'd love to see objects have a __render__ method which gets called to render them, and leave the __call__ method when they're being specifically called.. Then I guess dtml would need <dtml-render adn <dtml-call instead of just <dtml-var I guess I'm in the minority when it comes to seeing this as a good thing? ;-) <snip protocols thing?
This mechanism is pretty much separate from the __call__ mechanism.
That's all cool, but not what was causing me confusion...
In conclusion, I can't see any disadvantage to making Folder callable as I suggested in a previous message. It doesn't appear to break anything :-)
I'd agree, since it doesn't make my confusion over __call__ any worse..
IIRC, ZRenderable lets you choose what method you want __call__ to forward to, whereas ZCallable always chooses the method index_html, if it exists.
Ah, so ZCallable is an inferior ZRenderable? *joke* :-)
You have to do something like <dtml-var "nameofafolder.index_html(_.None, _)">. But, that's not quite the same because if the folder lacks an index_html, it gets acquired.
But index_html will get acquired with that method too as folders do Implicit acquisiton, or am I missing something? Hmm, I think the patch is good, has anyoen subitted it yet? cheers, Chris
Chris Withers wrote:
Ah, so ZCallable is an inferior ZRenderable? *joke* :-)
I made it 'cause it's simpler. And a memory lapse made me forget about Renderable. In fact I think ZCallable is a silly name. Actually the base class ought to be in standard Zope, not a product. And it should use the class-bound propertysheet stuff.
You have to do something like <dtml-var "nameofafolder.index_html(_.None, _)">. But, that's not quite the same because if the folder lacks an index_html, it gets acquired.
But index_html will get acquired with that method too as folders do Implicit acquisiton, or am I missing something?
Hmm, I think the patch is good, has anyoen subitted it yet?
Offhand I would say that putting a __call__ method in standard folders would break a lot of DTML. Remember that a namespace lookup tries to execute the value before returning it. But don't take my word for it, add a __call__ method to ObjectManager and see what happens. I've never tried it myself. :-) Shane
Shane Hathaway wrote:
Offhand I would say that putting a __call__ method in standard folders would break a lot of DTML. Remember that a namespace lookup tries to execute the value before returning it. But don't take my word for it, add a __call__ method to ObjectManager and see what happens. I've never tried it myself. :-)
I'm a chicken, if the content managers decide they need this, I'll roll my own folderish ZClass that has ZRenderabel as well ;-) cheers, Chris
participants (3)
-
Chris Withers -
Shane Hathaway -
Steve Alexander