Promlem getting the current object in PythonScript
Hi! I tried asking a question about this yesterday, and failed miserably in describing my problem. I apologize for that. Please read on. I have taken pains to write a very clear explanation with a code sample and precise data. My basic question is this: I have code which is called from standard_html_footer. When that code was a DTML Method, I used this(). Now that this code is a PythonScript, how do I access the same object? "context" and "context.this()" do not work reliably. Read more for details. I have a DTML Method called "adminMenu". That method is called in standard_html_footer like so: "<dtml-var adminMenu>". It prints nothing for anonymous users... But if the user is authenticated, it prints a context-sensitive admin menu. If the user is viewing a DTML Document to which he has "write access", the admin menu prints a "Edit this document" link. There are various other options. For many of them, I have to know which object the user is viewing. This works fine. But the "adminMenu" DTML Method soon grew big and cumbersome. Last week, I decided to re-write it as a PythonScript.. The code is mostly a port (very similar), and is called the same way: "<dtml-var adminMenu>" from the standard_html_footer. Yet I am now having problems getting a hold of the object which the user is viewing. Specifically, "context" never seems to refer to DTML Documents. It seems to ignore them like it does DTML Methods. An example: I use the following code to get my "debugging" information: print " <B>File name:</B> %s<BR>" % (context.getId()) print " <B>File type:</B> %s<BR>" % (context.meta_type) With a Folder... viewing http://www.levinux.org/ (a Folder) <B>File name:</B> levinux<BR> <B>File type:</B> Folder<BR> So far so good... With a DTML Document... viewing http://www.levinux.org/liens.html (a DTML Document) <B>File name:</B> levinux<BR> <B>File type:</B> Folder<BR> This is not expected behavior. My tests seem to indicate that, context.getId() and context.meta_type yield the same result as context.this().getId() and context.this().meta_type. So I am stumped. I am running Zope 2.3.1b2 (binary release, python 1.5.2, linux2-x86) on a Mandrake 7.2 system. Thanks for reading me. I hope you can help. Cheers, Jérôme Loisel -- Jérôme Loisel, étudiant et webmestre Lévinux: GNU/Linux pour la communauté http://www.levinux.org/
From: "Jérôme Loisel" <jerome@levinux.org>
My basic question is this: I have code which is called from standard_html_footer. When that code was a DTML Method, I used this(). Now that this code is a PythonScript, how do I access the same object? "context" and "context.this()" do not work reliably.
In this sort of situation, "context" is very different from "this()". Short answer: Use the Script's Bindings tab to bind the caller's namespace to "_" (or some other name) and use _["this"] to refer to the document. Long answer: When your document calls standard_html_footer, it acquires it from the document's context and passes the namespace to it. When standard_html_footer calls your Script, it gets it from the namespace, which acquires it from the original document's context. Now, the Script's context is the context of the original document, for instance the Folder containing that document. The only way that the Script's context could be the document is for the Script to be acquired from the document. DTML Documents don't implicitly acquire, so this can't happen. On the other hand, if the Script can get access to the document's namespace, it can ask the namespace for "this". The topmost object on the namespace stack that has "this" is the document, and calling it returns a reference to the document. Cheers, Evan @ digicool & 4-am
Hi! Evan Simpson -- Mercredi 04 Avril 2001 13:58:
From: "Jérôme Loisel" <jerome@levinux.org>
My basic question is this: I have code which is called from standard_html_footer. When that code was a DTML Method, I used this(). Now that this code is a PythonScript, how do I access the same object? "context" and "context.this()" do not work reliably.
In this sort of situation, "context" is very different from "this()".
Short answer:
Use the Script's Bindings tab to bind the caller's namespace to "_" (or some other name) and use _["this"] to refer to the document.
Hm... I really appreciate the info, but I am having *really* weird problems now. You can look at my script's source (the bound version). It is fairly readable and commented in English. It is all really simple stuff. http://zope.levinux.org/adminMenu.txt The weird problem is that binding namespace to _ radically changed my script's behavior. The first thing I noticed was that anonymous users were no longer allowed to view the site. Considering that my script starts with the following code... user = context.REQUEST.AUTHENTICATED_USER if user.getId() == None: return "" I find that weird. I can tell that the return does indeed work because nothing at all gets printed. Yet commenting out the three lines towards the end which refer to owner_info once again allower anonymous users to view the site. You can read the specfic error message I got on that problem here: http://zope.levinux.org/error1.html And remember that none of that happens if namespace is not bound... Having commented out the owner_info code, I was still not out of the woods. Authenticated AND unauthenticated users get errors when viewing any page: TypeError: no arguments expected. You can read the error message here: http://zope.levinux.org/error2.html Again, let me remind you that these errors only occur when I try to bind namespace to _. Am I going nuts or is this not expected behavior? Thanks in advance for all your help. Cheers, Jérôme PS: Fun with AUTHENTICATED_USER I ran some tests to see what happened to AUTHENTICATED_USER in PythonScript when binding the namespace. The sort answer is: nothing. Yet the following code yields very different behavior from the code in adminMenu.py: user = context.REQUEST.AUTHENTICATED_USER print "Hello!" print user.getId() return printed I get a Zope error: TypeError, call of non-function (type list). I find this very puzzling. You can see the full error message here: http://zope.levinux.org/error3.html The following code, however, raises no error: user = context.REQUEST.AUTHENTICATED_USER print "Hello!" print user return printed But for anonymous user, it returns "Anonymous User" instead of None. Yet trying to use if user == "Anonymous User" in Python code does not work. It raises no error, but always evaluates to false. I thought I was starting to know my way around Zope. But this is as confusing as it gets. Meesa not understand. -- Jérôme Loisel, étudiant et webmestre Lévinux: GNU/Linux pour la communauté http://www.levinux.org/
From: "Jérôme Loisel" <jerome@levinux.org>
The weird problem is that binding namespace to _ radically changed my script's behavior.
I'll check out the behavior you encountered in more detail later, but I do know that there was a bug in 2.3.0 (killed in CVS, and in 2.3.1) having to do with namespace binding. Are you using Zope 2.3.1? Cheers, Evan @ digicool & 4-am
Evan Simpson wrote:
I'll check out the behavior you encountered in more detail later, but I do know that there was a bug in 2.3.0 (killed in CVS, and in 2.3.1) having to do with namespace binding. Are you using Zope 2.3.1?
I'm seeing similar wierdness (so many post-its on my monitor about it they're starting to fall off ;-) Was this fixed in 2.3.1b1 or only 2.3.1 final? cheers, Chris
participants (3)
-
Chris Withers -
Evan Simpson -
Jérôme Loisel