Newbie: Missing a Variable (TAL/METAL Question)
Hi; I have the following block of code: <table tal:define="objects here/objectValues; sort_on python:(('title', 'nocase', 'asc'), ('bobobase_modification_time', 'cmp', 'desc')); sorted_objects python:sequence.sort(objects, sort_on); start python:getattr(request, 'start', 0); batch python:modules['ZTUtils'].Batch(sorted_objects, size=10, start=start); previous python:batch.previous; next python:batch.next"> <tr tal:repeat="item batch"> <td tal:content="item/title">title</td> <td tal:content="item/bobobase_modification_time"> modification date</td> <td tal:content="here/author">author</td> <td tal:content="here/content">content</td> </tr> </table> that works fine. But I'd like to call the following in that table: <td><tal:content metal:use-macro="here/XXX/macros/author"></tal:content></td> where "XXX" is the "item" that changes each time a new item from the batch is called. In other words, there is a folder with a "batch" of files, and each file is an "item". So, since the files' titles are simply sequential numbers, it would look something like this: <td><tal:content metal:use-macro="here/1/macros/author"></tal:content></td> <td><tal:content metal:use-macro="here/2/macros/author"></tal:content></td> <td><tal:content metal:use-macro="here/3/macros/author"></tal:content></td> ... How do I do that? Even better, is it possible to just open up each file and read its contents?? Thanks, Ben --------------------------------- Do you Yahoo!? Get on board. You're invited to try the new Yahoo! Mail Beta.
beno - wrote:
Hi; I have the following block of code:
<table tal:define="objects here/objectValues; sort_on python:(('title', 'nocase', 'asc'), ('bobobase_modification_time', 'cmp', 'desc')); sorted_objects python:sequence.sort(objects, sort_on); start python:getattr(request, 'start', 0); batch python:modules['ZTUtils'].Batch(sorted_objects, size=10, start=start); previous python:batch.previous; next python:batch.next"> <tr tal:repeat="item batch"> <td tal:content="item/title">title</td> <td tal:content="item/bobobase_modification_time"> modification date</td> <td tal:content="here/author">author</td> <td tal:content="here/content">content</td> </tr> </table> that works fine. But I'd like to call the following in that table:
<td><tal:content metal:use-macro="here/XXX/macros/author"></tal:content></td> where "XXX" is the "item" that changes each time a new item from the batch is called. In other words, there is a folder with a "batch" of files, and each file is an "item". So, since the files' titles are simply sequential numbers, it would look something like this:
<td><tal:content metal:use-macro="here/1/macros/author"></tal:content></td> <td><tal:content metal:use-macro="here/2/macros/author"></tal:content></td> <td><tal:content metal:use-macro="here/3/macros/author"></tal:content></td> ...
How do I do that? Even better, is it possible to just open up each file and read its contents??
Thanks, Ben
------------------------------------------------------------------------
Ben, First this is wrong: <td><tal:content ... If should be <td tal:content ... But that may be wrong in the context you've given. Since "do it in python" has been a theme lately, you can also return a macro from a python script like so: Where there is an author might be a parameter. #some python script # return container.YourMacroFolder.someMacro[ author ] ----------------------------------------------------------------------- And in your ZPT: (where result.author is just a stub for whatever your using) <td><span metal:use-macro="python: context.youPythonScript(result.author)">macro goes here</span></td> I suggest *always* doing stuff in python when things are not clear. Then code back into your Page Templates, if desired DAvid
beno - wrote at 2006-7-26 15:04 -0700:
... that works fine. But I'd like to call the following in that table:
<td><tal:content metal:use-macro="here/XXX/macros/author"></tal:content></td>
where "XXX" is the "item" that changes each time a new item from the batch is called.
You might try something like "here/?var/...". "?var" reads the contents of the variable "var" and inserts this content into the path expression. Note that the value must be a string and that embedded '/' are *not* treated as path separators. -- Dieter
I have done as you say and get this error: KeyError: '$var' Here are the code lines I added into the table: <td><tal:content metal:use-macro="here/$var/macros/author">author</tal:content></td> <td><tal:content metal:use-macro="here/$var/macros/content">content</tal:content></td> TIA, Ben Dieter Maurer <dieter@handshake.de> wrote: beno - wrote at 2006-7-26 15:04 -0700:
... that works fine. But I'd like to call the following in that table:
where "XXX" is the "item" that changes each time a new item from the batch is called.
You might try something like "here/?var/...". "?var" reads the contents of the variable "var" and inserts this content into the path expression. Note that the value must be a string and that embedded '/' are *not* treated as path separators. -- Dieter --------------------------------- Do you Yahoo!? Next-gen email? Have it all with the all-new Yahoo! Mail Beta.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 28 Jul 2006, at 09:45, beno - wrote:
I have done as you say and get this error:
KeyError: '$var'
Dieter said "?var", not "$var"... jens -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (Darwin) iD8DBQFEyhVLRAx5nvEhZLIRArVjAJ4wGFI60euFIRFdf7iqK9eEyrBVjgCdHfdt h9cTcnnUP7HEf/B76+iYH7E= =Hsz4 -----END PGP SIGNATURE-----
Right. My bad. However, that didn't work either :( The error was it couldn't find 'var'. So I tried 'item'. It couldn't find 'item'. So I tried this code: <td tal:define="number repeat/item/number" tal:content="number">1</td> and it complained that it couldn't find 'number'. TIA, beno Jens Vagelpohl <jens@dataflake.org> wrote: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 28 Jul 2006, at 09:45, beno - wrote:
I have done as you say and get this error:
KeyError: '$var'
Dieter said "?var", not "$var"... jens -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (Darwin) iD8DBQFEyhVLRAx5nvEhZLIRArVjAJ4wGFI60euFIRFdf7iqK9eEyrBVjgCdHfdt h9cTcnnUP7HEf/B76+iYH7E= =Hsz4 -----END PGP SIGNATURE----- _______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev ) --------------------------------- Do you Yahoo!? Everyone is raving about the all-new Yahoo! Mail Beta.
--On 28. Juli 2006 08:01:01 -0700 beno - <purabachata@yahoo.com> wrote:
Right. My bad. However, that didn't work either :( The error was it couldn't find 'var'. So I tried 'item'. It couldn't find 'item'. So I tried this code: <td tal:define="number repeat/item/number" tal:content="number">1</td>
and it complained that it couldn't find 'number'.
*Please* don't throw snippets without further context at us. We need some reasonable context information about the code around..if you do expect help then please provide some more accurate informations...most of us have little to think about what your real problem might be. -aj
beno - wrote at 2006-7-28 08:01 -0700:
Right. My bad. However, that didn't work either :( The error was it couldn't find 'var'.
I used "var" to indicate some variable. It was not meant that you use "var" literally...
So I tried 'item'. It couldn't find 'item'. So I tried this code:
<td tal:define="number repeat/item/number" tal:content="number">1</td>
and it complained that it couldn't find 'number'.
You must be very careful: both in reading and in writing. And you must try to understand how things work. And you must provide full error information (i.e. "Error Type", "Error Value" and the traceback -- you find all of them in the "error_log" object in your Zope "Root Folder"). If you use "repeat/variable" (again, "variable" is not meant literally, but *some* "variable"), then "variable" must be a repeat variable defined by an enclosing 'tal:repeat="variable ..."'. If this is the case, then "repeat/variable/number" should work. -- Dieter
Dieter Maurer <dieter@handshake.de> wrote:If you use "repeat/variable" (again, "variable" is not meant literally, but *some* "variable"), then "variable" must be a repeat variable defined by an enclosing 'tal:repeat="variable ..."'. If this is the case, then "repeat/variable/number" should work. Here is the code again: <table tal:define="objects here/objectValues; sort_on python:(('title', 'nocase', 'asc'), ('bobobase_modification_time', 'cmp', 'desc')); sorted_objects python:sequence.sort(objects, sort_on); start python:getattr(request, 'start', 0); batch python:modules['ZTUtils'].Batch(sorted_objects, size=10, start=start); previous python:batch.previous; next python:batch.next"> <tr tal:repeat="item batch"> <td tal:define="number repeat/item/number" tal:content="number">1</td> <td tal:content="item/title">title</td> <td><tal:content metal:use-macro="here/?number/macros/author">author</tal:content></td> <td><tal:content metal:use-macro="here/?number/macros/content">content</tal:content></td> <td tal:content="item/bobobase_modification_time"> modification date</td> </tr> </table> Here is the error it throws as reported through the TTW: Site Error An error was encountered while publishing this resource. KeyError Sorry, a site error occurred.Traceback (innermost last): Module ZPublisher.Publish, line 175, in publish_module_standard Module ZPublisher.Publish, line 132, in publish Module Zope.App.startup, line 204, in zpublisher_exception_hook Module ZPublisher.Publish, line 101, in publish Module ZPublisher.mapply, line 88, in mapply Module ZPublisher.Publish, line 39, in call_object Module Shared.DC.Scripts.Bindings, line 306, in __call__ Module Shared.DC.Scripts.Bindings, line 343, in _bindAndExec Module Products.PageTemplates.ZopePageTemplate, line 222, in _exec Module Products.PageTemplates.PageTemplate, line 96, in pt_render <ZopePageTemplate at /rejoice.2012.vi/en-us/Books/getQuote used for /rejoice.2012.vi/en-us/Books/test> Module TAL.TALInterpreter, line 190, in __call__ Module TAL.TALInterpreter, line 234, in interpret Module TAL.TALInterpreter, line 613, in do_loop_tal Module TAL.TALInterpreter, line 234, in interpret Module TAL.TALInterpreter, line 657, in do_useMacro Module Products.PageTemplates.TALES, line 221, in evaluate URL: /rejoice.2012.vi/en-us/Books/getQuote Line 22, Column 4 Expression: standard:'here/?number/macros/author' Names: {'container': <Folder instance at 9cb67a0>, 'context': <Folder instance at 9cd1e60>, 'default': <Products.PageTemplates.TALES.Default instance at 0x8a1d62c>, 'here': <Folder instance at 9cd1e60>, 'loop': <SafeMapping instance at 99ef7a0>, 'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at 0x8a1d06c>, 'nothing': None, 'options': {'args': ()}, 'repeat': <SafeMapping instance at 99ef7a0>, 'request': <HTTPRequest, URL=http://rejoice.2012.vi/Books/test/getQuote>, 'root': <Application instance at 9a4c8f0>, 'template': <ZopePageTemplate at /rejoice.2012.vi/en-us/Books/getQuote used for /rejoice.2012.vi/en-us/Books/test>, 'traverse_subpath': [], 'user': Anonymous User} Module Products.PageTemplates.Expressions, line 174, in __call__ Module Products.PageTemplates.Expressions, line 162, in _eval Module Products.PageTemplates.Expressions, line 101, in _eval KeyError: 'number' (Also, an error occurred while attempting to render the standard error message.) The error from the error log makes no sense to me. The time is off, too. I don't understand, but here it is: Time 2006/07/28 22:42:06.706 Universal User Name (User Id) tick (tick) Request URL http://2012.vi:7080/error_log/manage_workspace Exception Type Redirect Exception Value http://2012.vi:7080/error_log/manage_main Traceback (innermost last): Module ZPublisher.Publish, line 101, in publish Module ZPublisher.mapply, line 88, in mapply Module ZPublisher.Publish, line 39, in call_object Module App.Management, line 85, in manage_workspace Redirect: http://2012.vi:7080/error_log/manage_main Display traceback as text51 [input] 43 REQUEST formcookiestree-s'eJzT0MgpMOQKVneEA09bda4CI67EkgJjLj0AeJsHfw'lazy itemsSESSION<bound method SessionDataManager.getSessionData of <SessionDataManager instance at 9a56890>>otherTraversalRequestNameStack[]AUTHENTICATED_USERtickURL'http://2012.vi:7080/error_log/manage_workspace'SERVER_URL'http://2012.vi:7080'AUTHENTICATION_PATH''PUBLISHED<bound method SiteErrorLog.manage_workspace of <SiteErrorLog at /error_log>>URL1'http://2012.vi:7080/error_log'ACTUAL_URL'http://2012.vi:7080/error_log/manage_workspace'URL0http://2012.vi:7080/error_log/manage_workspaceURL1http://2012.vi:7080/error_logURL2http://2012.vi:7080BASE0http://2012.vi:7080BASE1http://2012.vi:7080BASE2http://2012.vi:7080/error_logBASE3http://2012.vi:7080/error_log/manage_workspaceenvironHTTP_COOKIE'tree-s="eJzT0MgpMOQKVneEA09bda4CI67EkgJjLj0AeJsHfw"'SERVER_SOFTWARE'Zope/(Zope 2.7.8-final, python 2.3.5, freebsd5) ZServer/1.1'SCRIPT_NAME''REQUEST_METHOD'GET'PATH_INFO'/error_log/manage_workspace'SERVER_PROTOCOL'HTTP/1.1'channel.creation_time1154126516CONNECTION_TYPE'keep-alive'HTTP_ACCEPT_CHARSET'ISO-8859-1,utf-8;q=0.7,*;q=0.7'HTTP_USER_AGENT'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4'HTTP_REFERER'http://2012.vi:7080/manage_main'SERVER_NAME'localhost'REMOTE_ADDR'67.143.135.132'PATH_TRANSLATED'/error_log/manage_workspace'SERVER_PORT'7080'HTTP_HOST'2012.vi:7080'HTTP_ACCEPT'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'GATEWAY_INTERFACE'CGI/1.1'HTTP_ACCEPT_LANGUAGE'en-us,en;q=0.5'HTTP_ACCEPT_ENCODING'gzip,deflate'HTTP_KEEP_ALIVE'300' --------------------------------- Talk is cheap. Use Yahoo! Messenger to make PC-to-Phone calls. Great rates starting at 1¢/min.
En/na beno - ha escrit:
Here is the error it throws as reported through the TTW:
Site Error
An error was encountered while publishing this resource. *KeyError* Sorry, a site error occurred. Traceback (innermost last):
number is defined *only* in the block where you define it and enclosed blocks, in the first <TD> in your case. IIRC TAL provides a way to make a variable global, not sure, never used it. A more structured way would be to wrap all <TD>s with some block that defines number: <div tal:define="number repeat/item/number" tal:omit-tag=""> <td tal:content="number"></td> ... metal:use-macro="here/?number/macros/author" ... ... </div> HTH
beno - wrote at 2006-7-28 15:43 -0700:
... <tr tal:repeat="item batch"> <td tal:define="number repeat/item/number" tal:content="number">1</td> <td tal:content="item/title">title</td> <td><tal:content metal:use-macro="here/?number/macros/author">author</tal:content></td> ... Traceback ... Line 22, Column 4 Expression: standard:'here/?number/macros/author' ... KeyError: 'number' (Also, an error occurred while attempting to render the standard error message.)
The traceback tells you (kept part) that the "KeyError: 'number'" comes from "here/?number/macros/author" and it is right: Unless you use "global", variables defined in TAL only live within the element (aka "tag") you have defined them in. In your special case, this is the "td" element. It it not defined in the following "td"s. A common approach is to use artificial "block" elements to carry the definitions for some elements in the loop body -- similar to <tr tal:repeat="..."> <tal:block define="number ..."> <td tal:content="number" /> ... <td><tal:content metal:use-macro="here/?number/..." /></td> ... </tal:block> </tr> Apparently, you already use "tal" prefixed tag names. The "tal:block" is another standard use... Another advice: carefully read the PageTemplate section in the Zope Book (2.7 edition, on "plope.org"). -- Dieter
Alexis Rhoda's suggestion sounds similar. I edited the code as follows, both with and without the 'global' parameter with the same error thrown. I read the material you recommended before writing the list and have been referencing it. I confess that snakes would bite me repeatedly though before my eyes for lack of seeing them, no matter how hard I try. Your further help would be very much appreciated. TIA, beno <tr tal:repeat="item batch"> <tal:block define="global number repeat/item/number"> <td tal:content="number">1</td> <td tal:content="item/title">title</td> <td><tal:content metal:use-macro="here/?number/macros/author">author</tal:content></td> <td><tal:content metal:use-macro="here/?number/macros/content">content</tal:content></td> <td tal:content="item/bobobase_modification_time"> modification date</td> </tal:block> </tr> 3 TypeError Sorry, a site error occurred.Traceback (innermost last): Module ZPublisher.Publish, line 175, in publish_module_standard Module ZPublisher.Publish, line 132, in publish Module Zope.App.startup, line 204, in zpublisher_exception_hook Module ZPublisher.Publish, line 101, in publish Module ZPublisher.mapply, line 88, in mapply Module ZPublisher.Publish, line 39, in call_object Module Shared.DC.Scripts.Bindings, line 306, in __call__ Module Shared.DC.Scripts.Bindings, line 343, in _bindAndExec Module Products.PageTemplates.ZopePageTemplate, line 222, in _exec Module Products.PageTemplates.PageTemplate, line 96, in pt_render <ZopePageTemplate at /rejoice.2012.vi/en-us/Books/getQuote used for /rejoice.2012.vi/en-us/Books/test> Module TAL.TALInterpreter, line 190, in __call__ Module TAL.TALInterpreter, line 234, in interpret Module TAL.TALInterpreter, line 613, in do_loop_tal Module TAL.TALInterpreter, line 234, in interpret Module TAL.TALInterpreter, line 409, in do_optTag_tal Module TAL.TALInterpreter, line 394, in do_optTag Module TAL.TALInterpreter, line 389, in no_tag Module TAL.TALInterpreter, line 234, in interpret Module TAL.TALInterpreter, line 657, in do_useMacro Module Products.PageTemplates.TALES, line 221, in evaluate URL: /rejoice.2012.vi/en-us/Books/getQuote Line 22, Column 8 Expression: standard:'here/?number/macros/author' Names: {'container': <Folder instance at e909350>, 'context': <Folder instance at 92e1ad0>, 'default': <Products.PageTemplates.TALES.Default instance at 0x8a1d62c>, 'here': <Folder instance at 92e1ad0>, 'loop': <SafeMapping instance at 8ff2380>, 'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at 0x8a1d06c>, 'nothing': None, 'options': {'args': ()}, 'repeat': <SafeMapping instance at 8ff2380>, 'request': <HTTPRequest, URL=http://rejoice.2012.vi/Books/test/getQuote>, 'root': <Application instance at 90c1f80>, 'template': <ZopePageTemplate at /rejoice.2012.vi/en-us/Books/getQuote used for /rejoice.2012.vi/en-us/Books/test>, 'traverse_subpath': [], 'user': Anonymous User} Module Products.PageTemplates.Expressions, line 174, in __call__ Module Products.PageTemplates.Expressions, line 162, in _eval Module Products.PageTemplates.Expressions, line 107, in _eval TypeError: iteration over non-sequence (Also, an error occurred while attempting to render the standard error message.) --------------------------------- Dieter Maurer <dieter@handshake.de> wrote: beno - wrote at 2006-7-28 15:43 -0700:
...
tal:content="number">1 title author ... Traceback ... Line 22, Column 4 Expression: standard:'here/?number/macros/author' ... KeyError: 'number' (Also, an error occurred while attempting to render the standard error message.)
The traceback tells you (kept part) that the "KeyError: 'number'" comes from "here/?number/macros/author" and it is right: Unless you use "global", variables defined in TAL only live within the element (aka "tag") you have defined them in. In your special case, this is the "td" element. It it not defined in the following "td"s. A common approach is to use artificial "block" elements to carry the definitions for some elements in the loop body -- similar to ... ... Apparently, you already use "tal" prefixed tag names. The "tal:block" is another standard use... Another advice: carefully read the PageTemplate section in the Zope Book (2.7 edition, on "plope.org"). -- Dieter --------------------------------- Groups are talking. We´re listening. Check out the handy changes to Yahoo! Groups.
beno - wrote at 2006-7-29 10:09 -0700:
... <tr tal:repeat="item batch"> <tal:block define="global number repeat/item/number"> <td tal:content="number">1</td> <td tal:content="item/title">title</td> <td><tal:content metal:use-macro="here/?number/macros/author">author</tal:content></td> <td><tal:content metal:use-macro="here/?number/macros/content">content</tal:content></td> <td tal:content="item/bobobase_modification_time"> modification date</td> </tal:block> </tr> ... Sorry, a site error occurred.Traceback (innermost last): ... Line 22, Column 8 Expression: standard:'here/?number/macros/author' ... Module Products.PageTemplates.Expressions, line 107, in _eval TypeError: iteration over non-sequence (Also, an error occurred while attempting to render the standard error message.)
This one is a bit more difficult: you need to look at the source code to find out what goes wrong. The traceback again tells you that the problem is with "here/?number/macros/author". Moreover, it tells you that the exception is raised in line 107 of "Module Products.PageTemplates.Expressions". The code, you see there is "path[i:i+1] = list(val)". I see from this code (it is okay when you do not yet see it), that "list(val)" is the problem. You must now look a bit around and take names seriously. The code aroung is: if self._dp: path = list(path) # Copy! for i, varname in self._dp: val = vars[varname] if isinstance(val, StringType): path[i] = val else: # If the value isn't a string, assume it's a sequence # of path names. path[i:i+1] = list(val) This loop is responsible to replace the "?varname" occurrencies in your path by the value of the variable "varname". As you see, the value may either be a string or a sequence of paths. In your case, it is an integer and "list(<some_integer>)" results in the "TypeError" you observe. Add "number python:`number`" after your definition of "number", i.e. <tal:block define="number repeat/item/number; number python:`number`"> I removed the "global" (as you no longer need it due to the introduction of "tal:block"). The "`...`" is a Python operator equivalent to a call to "repr(...)" which converts into a string. -- Dieter
--On 28. Juli 2006 06:45:34 -0700 beno - <purabachata@yahoo.com> wrote:
I have done as you say and get this error:
KeyError: '$var'
Here are the code lines I added into the table:
<td><tal:content metal:use-macro="here/$var/macros/author">author</tal:content></td> <td><tal:content metal:use-macro="here/$var/macros/content">content</tal:content></td>
Please read carefully. There is no documentation that told you about "$var". You might use "?var" instead. -aj
participants (6)
-
Alexis Roda -
Andreas Jung -
beno - -
David H -
Dieter Maurer -
Jens Vagelpohl