[Zope-dev] Re: more __call__ ...

Jim Fulton jim@digicool.com
Tue, 26 Sep 2000 11:32:17 -0400


Chris Withers wrote:
> 
> (moving back onto list, hopefully my head/wall contact will save others
> braincells ;-)
> 
> Jim Fulton wrote:
> > > On an (almost) related matter, are there any docs (other than the code
> > > ;-) for how __call__ is handles WRT to <dtml-var something>?
> > > I had a look at DTMLMethod.py and PythonMethod.py and ended up very
> > > confused...
> >
> > Currently, DTML looks at something that it is going to render
> > and tries to decide if it's callable. If it is, it checks to
> > see if it has a true isDocTemp attribute. If an object is callable
> > and has a true isDocTemp, then it is called with None and the DTML
> > namespace. Otherwise, if an object is callable, it is just called.
> 
> So, if I give my product a class attribute of isDocTemp=1, what
> signature should I give my product's __call__ method so it picks up the
> DTML namespace?

  def __call__(self, ignored, md): ...

> > We are going to provide an alternate interface, so that if
> > an object has a special method, then this will be called instead.
> 
> okay... which proposal/project is this in?

I don't remember. Evan?
 
> > > I think the 'client', rather than 'self' is what I'm after, but how can
> > > I get it inside my product's __call__ method?
> 
> Hmmm... I don't suppose there's a nice definition of what the 'client'
> is, what's likely to be in the namespace stack and what self is likely
> to be in these circumstances lying around anywhere, is there? ;-)
  
client is just a namespace, defined by it's attributes. It's not really
in the namespace. Neither is self.
 
> > You can't really.  You should be able to infer it from the acquisition
> > context. For example, 'client' should be aq_parent.
> 
>     def __call__(self):
>         """ """
>         print self.aq_parent.id
> 
> This is called by a <dtml-var myObject> in standard_html_header which is
> also called with a dtml-var in, lets say, the DTML documnet: myDocument.
> 
> The above code prints the id of this product instance's container.

That's what I expect. 'client', in DocumentTemplate is usually
the object the template was invoked on.

> I was
> expecting it to print the id of myDocument. Is this me misunderstanding
> what the 'client' is,

Yes.

> or is something else going on?
> 
> In either case, what do I need to go to get hold of what would be
> PARENTS[0-1], if you see what I mean?

I don't see what you mean.  
 
> > Note that subtemplates
> > are not invoked on the objects they are found in, but in the namespace
> > they are called in. This is a bit weird and not really intensional. :(
> 
> I think I'm probably going to be relying on this, and I _think_ it makes
> sense to me. I presume subtemplate calls are things like doing <dtml-var
> myObject>?

That's fine.

> In which case it seems sensible to keep playing in the
> namespace and just popping myObject on top as an instanceDict. I'm note
> quite sure how you think this area should work adn what difference it
> would make, could you elaborate? :-S

First, I have no intention of changing anything in a backward
incompatible way. For that matter, I don't have much interest in
changing DTML at this point, given:

http://dev.zope.org/Wikis/DevSite/Projects/XHTMLTemplate

I think that if you say:

  <dtml-var expr="foo.bar">

that foo's namespace should take precedence over
the DTML namespace, but, in fact, foo's namespace
is ignored. I think that this should at least
happen optionally.  Otherwise, how could you think
of bar as a method?

 
> > > PS: In python product terms, whats' the difference between implementing
> > > __call__, __str__ or render?
> >
> > render?
> 
> Yeah, that's what I thought, but a coupla people have mentioned it.
> Maybe they're thinking of DTML tags?

Well, a number of people have suggested that there should
be a separate render (ie call as subtemlpate) interface. 
Maybe that's what what you meant.

Evan, help me out here. :)
 
> > __call__ implements the () operator (in C++ terms). It is the method
> > you implement to make your object callable.
> >
> > __str__ is the method you implement to control how your object is
> > converted to a human readable string.
> 
> So what's the difference in terms of doing <dtml-var myobject> and
> http://site.com/myobject, if there is any?

The difference is clearer if you have 

  http://site.com/foo/bar

vs 

  <dtml-var expr="foo.bar">

in http://site.com/zoo/splat.

In the former case, foo's namespace is 
at the top of the stack and, in the second case, 
it's not on the stack.

> PS: What I'm actually looking for out of all of this is the
> getPhysicalPath() of the final object that was traversed through the
> URL.
> e.g: If the URL was http://www.nipltd.com/folder/somethingelse/myobject,
> I'm looking for something like:
> [<Application Instance at 0x000000> (Zope) , <Folder Instance at
> 0x000000> (folder) , <DTMLDocument Instance at 0x000000> (myobject)]

getPhysicalPath returns a list of strings, not objects.
 
> If there's an easier way to get this from within the __call__ method of
> a python product, someone PLEASE tell me! ;-)

aq_chain(x, 1)[-1:] should give this to you, I believe, or
be very close. :)

Jim

--
Jim Fulton           mailto:jim@digicool.com
Technical Director   (888) 344-4332              Python Powered!
Digital Creations    http://www.digicool.com     http://www.python.org

Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email
address may not be added to any commercial mail list with out my
permission.  Violation of my privacy with advertising or SPAM will
result in a suit for a MINIMUM of $500 damages/incident, $1500 for
repeats.