[Zope] Argument passing and DTMLFile methods
Terry Hancock
hancock@anansispaceworks.com
Sun, 30 Jun 2002 08:01:27 -0700
Dieter Maurer wrote:
> Terry Hancock writes:
> > ....
> > EXCEPT... :-(
> >
> > This only works if I use *implicit* dtml-var substitutions,
> > like:
> >
> > <dtml-var mydtml_submethod>
> >
> > If I try to use the explicit form mentioned above,
> >
> > <dtml-var expr="mydtml_submethod(_.None, _)">
> >
> > I lose my context!
> In a Python method context, this looks like
>
> mydtml_submethod(self, self.REQUEST, keyword_parameters)
Okay, I guess this would work from a Python method (I
haven't tried that yet -- though I suppose I could write
a wrapper that way -- call the python method, then call
the DTMLFile method -- but then I'd lose my context there
too, I think, since Python doesn't support the implicit
passing that DTML does).
>From another DTMLFile method, though, as in:
<dtml-var expr="mydtml_submethod(self,self.REQUEST,
keywordparm=keywordval)">
this gives the same unfortunate results I had with passing "_.None, _"
(just tested it).
For the "client", I've since tried "this, _.this, _.this(), context,
'context'". All seem to have the same effect (actually _.this()
generates
an error indicating that _.this isn't callable -- sort of a relief,
since it proved I was actually having some effect!).
I also tried changing the DTMLFile from a class method to
an instance method. I.e. changing from:
class my_class(Folder):
mydtml_method = DTMLFile('dtml/mydtml_method', globals())
mydtml_submethod = DTMLFile('dtml/mydtml_submethod', globals())
to
class my_class(Folder):
def __init__(self):
self.mydtml_method = DTMLFile('dtml/mydtml_method', globals())
self.mydtml_submethod = DTMLFile('dtml/mydtml_submethod', globals())
But this doesn't seem to work. I wonder if this actually
makes any difference, since presumeably the class methods
are inherited by the instance anyway. (I think it does
mean I have to recreate the object to allow changes to take
effect -- I'm not certain I verified this to be true, though
I do re-create the object just to be sure).
Also, I still don't really understand what I'm doing
here -- for example, where exactly *is* the caller's
namespace in this example?
I've called an object method through the web:
HTTP_REQUEST --> my_object.mydtml_method
Then that method is calling another method on the same
object:
my_object.mydtml_method --> my_object.mydtml_submethod
So, is the client "my_object"? Does this mean that the
DTML names are in "my_object"'s __dict__ (or something
equivalent to that?).
I can't really refer to the object explicitly, since I
would need to know the instance name. (I'm sure there's
a round-about way to do it, if I think about it hard
enough).
The thing that baffles me, is that:
<dtml-let keywordparm=keywordval>
<dtml-var mydtml_submethod>
</dtml-let>
works just fine (I've tested it several times). I guess
that'll be my work-around if I can't figure out how
to do it "right", but the problem makes me think I
don't understand what I'm doing and might well shoot
myself in the foot.
Also, it's clear that Zope somehow *can* do what I
want, since it does it for the implicit case.
I've been trying to sort out the DTML processing code,
following the traceback, which is, as I said, pretty
hairy to read.
It DOES appear that a "DTMLFile method" is indeed a
different beast than either "DTML Method" or
"DTML Document", and an underdocumented one -- a search
for "DTMLFile" on www.zope.org turns up depressingly
few references, and most of those are to using it for
manage_add<product>Form methods.
I know that the "globals()" call in the DTMLFile()
constructor call is needed to find the correct location
of the file -- does it do anything else? Can one set
the client in the constructor call (or am I doing that
by making it a method of the class or the class instance?).
I made a sample product for this problem, which is at the
URL below. As is, it doesn't work -- you have to alter
the commented-out lines in "dtml/test_form_dtml" to
see the "correct" output (just look for the <dtml-comment>
element -- it's pretty obvious actually):
http://www.anansispaceworks.com/Download/TestProduct.tgz
Any comments on this example would be appreciated.
> http://www.dieter.handshake.de/pyprojects/zope/book/chap3.html
And thanks for the book reference, Dieter (earlier
in the DTML arguments thread that preceded this) -- is
that your manuscript for Wrox? It looks pretty good so far.
Looking at the section in there on calling "DTML Objects",
I notice that it says that for "DTML Methods" there is
no client, but that the caller's names are passed in the
REQUEST.
Am I barking up the wrong tree then? Is it the REQUEST
variable that I'm getting wrong?
Oh, I just found out one more thing -- if I change the
web REQUEST to:
...my_class/mydtml_method?implicitvar=override
Then the value "override" will be passed to mydtml_submethod,
and the call succeeds! In other words, passing "_" is passing
the REQUEST but not the namespace within mydtml_method.
Does *that* mean anything to anyone?
Well, I'm still thrashing around quite a bit -- not
sure what sort of problem I have yet, so any suggestions
would be appreciated.
Thanks!
Terry
--
------------------------------------------------------
Terry Hancock
hancock@anansispaceworks.com
Anansi Spaceworks
http://www.anansispaceworks.com
P.O. Box 60583
Pasadena, CA 91116-6583
------------------------------------------------------