[Zope] odd behavior when External Method calls DTML Method

Brian Withun brianw@hilgraeve.com
Wed, 17 Apr 2002 13:00:02 -0400


> I would name your external method something else
> to be on the safe side - "URL" seems like it
> would be likely to have name collisions.

There's no collision because I'm expecting to use the built-in REQUEST.URL.

I tried to come up with a minimal reproducible example illustrating the
error I am experiencing.  I chose 'URL' specifically because it is ALWAYS
available in the REQUEST object.  It is not a method or object of my
creation.  Perhaps it would have been clearer if I chose a more obvious
REQUEST attribute such as SERVER_URL...

I think my question is better asked, "how do I call a DTML Method from
an External Method?"

Here is another attempt to illustrate my problem.  I'm using
REQUEST.SERVER_URL
rather than REQUEST.URL, but it's the same behavior.

----------------------------(DMTL Method at /Test/test_dtml)
<p> &lt;dtml-var SERVER_URL&gt; :
  <dtml-try>
    <dtml-var SERVER_URL>
  <dtml-except KeyError>
    didn't work - KeyError
  </dtml-try>
</p>

<p> &lt;dtml-var "_['SERVER_URL']"&gt; :
  <dtml-try>
    <dtml-var "_['SERVER_URL']">
  <dtml-except KeyError>
    didn't work - KeyError
  </dtml-try>
</p>

<p> &lt;dtml-var "REQUEST.SERVER_URL"&gt; :
  <dtml-try>
    <dtml-var "REQUEST.SERVER_URL">
  <dtml-except KeyError>
    didn't work - KeyError
  </dtml-try>
</p>
----------------------------(end DTML Method)

When I browse to http://myserver.com/Test/test_dtml, I see this: (as
expected)

  <dtml-var SERVER_URL> : http://myserver.com
  <dtml-var "_['SERVER_URL']"> : http://myserver.com
  <dtml-var "REQUEST.SERVER_URL"> : http://myserver.com

But when I browse to http://myserver.com/Test/test_method, I see this
(unexplained)

  <dtml-var SERVER_URL> : didn't work - KeyError
  <dtml-var "_['SERVER_URL']"> : didn't work - KeyError
  <dtml-var "REQUEST.SERVER_URL"> : http://myserver.com

Why does only the third expression syntax work?

test_method is just an External Method which calls the same DTML Method:

-------------------------(External Method at /Test/test_method)
def Test_test1( self ):
  return self.Test.test1_dtml( self.XmlRpc.Test,self )
-------------------------(end External Method)

ASIDE:
It is my understanding that, when zope executes an External Method, the
first argument is implicitly "self", which represents the Zope namespace.
In my case, my external method is called with no arguments (via a browser),
yet receives one implicit argument; the Zope.
This allows the called External Method to access elements inside of Zope
which it would otherwise not be able to do.

So I call a DTML Method inside of the Zope (from the External Method) by
accessing self.Test.test1_dtml.  "self" represents the zope application
and ".Test" represents the Test folder, and ".test1_dtml" represents my
DTML Method within that folder.

Once there, however, Zope doesn't seem to be traversing the _existing_
REQUEST object for names.  I get a KeyError while accessing a variable
that I _know_ is in the REQUEST.  The sample code above pretty much
proves that (at least to me).

Why does <dtml-var "REQUEST.SERVER_URL"> work when <dtml-var SERVER_URL>
does not?

I hope I've made it more clear this time :-)

Brian Withun

AIM: BHWITHUN
Y! Messenger: BHWITHUN


-----Original Message-----
From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of
Thomas B. Passin
Sent: Wednesday, April 17, 2002 11:36 AM
To: Zope mailing list
Subject: Re: [Zope] odd behavior when External Method calls DTML Method


[Brian Withun]

>
> I am experiencing some kind of acquisition problem when calling DTML
Methods
> from External Methods
>
> In a nutshell, I have a dtml method:
>
> ---------------------(test1_dtml)---
> <dtml-var URL>
> ------------------------------------
>
>...
>   File /usr/local/Zope-2.5.0-linux2-x86/lib/python/OFS/DTMLMethod.py, line
> 127, in __call__
>     (Object: test1_dtml)
>   File
> /usr/local/Zope-2.5.0-linux2-x86/lib/python/DocumentTemplate/DT_String.py,
> line 473, in __call__
>     (Object: test1_dtml)
> KeyError: URL
>
> This is the module containing the function for my External Method:
>
> --------------------(myModule.py)---
> def test1( self ):
>   return self.Test.test1_dtml( self )
> ------------------------------------
>
> Curiously, though my DTML Method '''<dtml-var URL>''' does not work, if I
> change it
> to '''<dtml-var "REQUEST.get('URL')">''' it works fine.  ?????
>


This is not the correct way to write an external method.  First of all,
Python does not have a "self" parameter or property.  The name is used, by
convention, in defining classes, and has nothing to do with function
definitions.  Even though you may call it "self", it is just a parameter to
be passed in like any other.

You need to figure out what object reference to send to the external method.
Remember, when you modify the external method, you have to save it again in
the "properties" tab for the page of that method, otherwise Zope won't know
about your changes.

But you aren't passing any argument to the function - none is passed by
default to an external method.  So you should see an error "not enough
arguments", which you don't.

I can't say why "URL" is not being found - is that really the id of the
external method?  If it were defined in the parent page of the dtml method,
that might explain why it wasn't found.

If

<dtml-var "REQUEST.get('URL')">

succeeds, as you say, it indicates that your REQUEST object has a 'URL'
property, and has nothing to do with the external method.  I would name your
external method something else to be on the safe side - "URL" seems like it
would be likely to have name collisions.

Cheers,

Tom P



_______________________________________________
Zope maillist  -  Zope@zope.org
http://lists.zope.org/mailman/listinfo/zope
**   No cross posts or HTML encoding!  **
(Related lists -
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope-dev )