Including Script-Generated String in Method Call
I have been chasing my tail on this one for the better part of two hours now. Time to ask for help. My goal: I want to load a page whose URL looks like "day1.html" where the number in the name of the page changes. I have written a Python script called pagetoget which calculates the day number correctly and assembles the URL as a string, which it returns. This seems to work. In the page where I want to include this page, I essentially had only three lines: <dtml-var standard_html_header> <dtml-var pagetoget> <dtml-var standard_html_footer> That produces a page which contains the string of the URL, naturally. Not what I had in mind, but that's clearly what it should do. So the question I spent the better part of the evening on is how I get the string generated by the Python script to be callable from a DTML Document so that the page named by the string value gets displayed. I've tried everything I can think of. I finally decided I had to do a redirect, so I coded this: <dtml-call "RESPONSE.redirect(<dtml-call pagetoload>)"> On this, I get an invalid syntax error. I've tried mucking with the quotation marks (which are annoying as heck, as I'm sure everyone already knows) but nothing I tried worked. I just cannot get that syntax right. I've also tried using dtml-var instead of dtml-call in both places; no joy. Am I on the right track? Is there a better way to do this? This has to be something that hundreds of you experienced Zope dudes have done hundreds of times, but the documentation is either missing or difficult to find with search mechanisms. I'm going to keep at it but I'm getting pretty discouraged. Seems like this should be so easy.... -- Dan Shafer, Author-Consultant http://www.danshafer.com http://www.shafermedia.com
You can avoid the redirect using Zope function render(). For instance, if the object to display is in the current folder (PARENTS[0]), you can write: <dtml-var "_.render(_.getattr(PARENTS[0], name_of_the_doc_to_display ))"> where name_of_the_doc_to_display is a string. Of course, render() can be called on any object. Recall that paths like foo/bar/doc are "equivalent" to foo.bar.doc Hope this help, Emmanuel
At 8:54 AM +0100 12/30/01, Emmanuel Viennet wrote:
You can avoid the redirect using Zope function render().
For instance, if the object to display is in the current folder (PARENTS[0]), you can write:
<dtml-var "_.render(_.getattr(PARENTS[0], name_of_the_doc_to_display ))">
where name_of_the_doc_to_display is a string.
Of course, render() can be called on any object. Recall that paths like foo/bar/doc are "equivalent" to foo.bar.doc
Thanks. That was informative. But it doesn't seem to work. I get an AttributeError on __getslice__. The document I'm trying to render and the Python script that generates the string of the URL are both in the same folder as the page where this error occurs. I'm stumped. Maybe I need to make my Python script an external method?
Hope this help, Emmanuel
-- Dan Shafer, Author-Consultant http://www.danshafer.com http://www.shafermedia.com
Dan Shafer wrote:
Thanks. That was informative. But it doesn't seem to work. I get an AttributeError on __getslice__. The document I'm trying to render and the Python script that generates the string of the URL are both in the same folder as the page where this error occurs.
I'm stumped.
So am i :-) Is your document is a DTML Document ?
Maybe I need to make my Python script an external method?
No, I don't think so. Any method returning a *string* will do the job. Did you try replacing yopur methoid call by a string ? that is, replacing <dtml-var "_.render(_.getattr(PARENTS[0], pagetoget ))"> by <dtml-var "_.render(_.getattr(PARENTS[0], "the_name_of_your_doc" ))"> ? -- Emmanuel Viennet Dpt GTR - IUT de Villetaneuse - Universite Paris-Nord 93430 Villetaneuse - France http://www-gtr.iutv.univ-paris13.fr/
At 2:22 PM +0100 12/30/01, Emmanuel Viennet wrote:
Dan Shafer wrote:
Thanks. That was informative. But it doesn't seem to work. I get an AttributeError on __getslice__. The document I'm trying to render and the Python script that generates the string of the URL are both in the same folder as the page where this error occurs.
I'm stumped.
So am i :-)
Is your document is a DTML Document ?
Yes, both the document I'm editing here and the one I want to load are DTML documents.
Maybe I need to make my Python script an external method?
No, I don't think so. Any method returning a *string* will do the job.
Did you try replacing yopur methoid call by a string ? that is, replacing <dtml-var "_.render(_.getattr(PARENTS[0], pagetoget ))"> by <dtml-var "_.render(_.getattr(PARENTS[0], "the_name_of_your_doc" ))">
Yes, I did that. That works with the name of the file I want to load placed inside single quotation marks. The Python script is pretty simple and I don't see how it can be returning a wrong result: daynum="1" return 'day'+daynum+'.html' When I test that script in Zope, it returns a string of the right contents! This is quite bewildering.
?
-- Emmanuel Viennet Dpt GTR - IUT de Villetaneuse - Universite Paris-Nord 93430 Villetaneuse - France http://www-gtr.iutv.univ-paris13.fr/
-- Dan Shafer, Author-Consultant http://www.danshafer.com http://www.shafermedia.com
Thanks to clues from Emmanuel Viennet and from Bak, each of whom supplied a piece of the puzzle, and to a more careful re-reading of Chapter 8 of The Zope Book, I finally fixed this problem. It turned out I had two compunding misunderstandings/errors. First, to call the Python script in a DTML context, I needed the script to be in quotation marks (which I had) BUT I also needed the function parens for it to work. Second, I learned the rule that you can't put DTML into a DTML tag. That was illuminating. It also helped me understand why the call to _render that Bak suggested wasn't working for me when I called the script but did work if I supplied a string. So here is what I ended up with: <dtml-let pagetoload="pagetoget()"> <dtml-var "_.render(_.getattr(PARENTS[0], pagetoload ))"> </dtml-let> The Script Object ios called pagetoget. I assign its return value to the DTML variable pagetoload. Then I use pagetoload as an argument to the _.getattr builtin and pass the whole thing to _.render (which I didn't find documented anywhere but I'm grateful to you guys for pointing me to it) and, voila!, the page loads. I'm going to write a HowTo on this one because I suspect it's something a lot of people have had to figure out the hard way. Now to figure out how to get a HowTo submitted on Zope.org. Thanks again. -- Dan Shafer, Author-Consultant http://www.danshafer.com http://www.shafermedia.com
Bravo ! render(), and other builtin functions, is documented in the "DTML reference", appendix A of The Zope Book. See http://www.zope.org/Members/michel/ZB/AppendixA.dtml Emmanuel
At 9:23 AM +0100 12/31/01, Emmanuel Viennet wrote:
Bravo !
render(), and other builtin functions, is documented in the "DTML reference", appendix A of The Zope Book.
I had looked and not found it. My alphabetic reference goes from "random" to "return" but when I got your note, I looked more closely and there it is, listed among the DTML functions. It would probably have been helpful if those functions had been listed alphabetically with the rest of the DTML reference material, with a "see DTML Functions" cross-reference. Thanks for the pointer.
See http://www.zope.org/Members/michel/ZB/AppendixA.dtml
Emmanuel
-- Dan Shafer, Author-Consultant http://www.danshafer.com http://www.shafermedia.com
participants (2)
-
Dan Shafer -
Emmanuel Viennet