Flexible path generation for metal:use-macro with Python (KeyError)
I am looking for a flexible way to define the path for a macro to be used. The following works: <span metal:use-macro="here/content_macro_main.html/macros/main | here/content_macros.html/macros/main | here/content_macros.html/macros/no_main_content"> It tries to locate the macro "main" first in the file content_macro_main.html and if that fails, ZOPE tries to find it in content_macros.html and if that fails too, the macro "no_main_content" in content_macros.html is called. Now, I would like to generate this sequence of alternative paths by a Python script to have full flexibility. Therefore I tried the following approach: Create a Python "getMacroPath" script that takes the parameter "macroname" and looks like this: return 'here/content_macro_main.html/macros/' + macroname (Of course, the script will finally generate many paths separated by "|") In the ZOPE Page Template mydoc.html I use: <span tal:omit-tag="" tal:define="macropath python:here.getMacroPath('main')"> <span metal:use-macro="here/?macropath"> <!-- main slot --> <H2>Welcome</H2> <P>We welcome you to our website.</P> </span> </span> The Python script seems to work correctly, but ZOPE complains with the error: Error Type: KeyError Error Value: here/content_macro_main.html/macros/main However, I don't see why METAL and/or ZOPE cannot deal with a TAL variable that has the correct value when it can deal with the same value as a string itself. Any ideas? Regards, Thomas Duebendorfer
On Wed, 2002-12-04 at 10:49, Thomas Duebendorfer wrote:
In the ZOPE Page Template mydoc.html I use: <span tal:omit-tag="" tal:define="macropath python:here.getMacroPath('main')"> <span metal:use-macro="here/?macropath"> <!-- main slot --> <H2>Welcome</H2> <P>We welcome you to our website.</P> </span> </span>
That ?macropath in the use-macro needs to be _one_ element only. This has come up before - and I agree with you, it would be easier ;) I ended up going out to zope product land, and writing something that returned not the name of the macro, but the actual macro itself: security.declarePublic('getMacro') def getMacro(self,macroFile,macro='std'): """ Generic "get a macro" method - this handles skinning. Should handle this as a modified traversal on the skins folder, by rights - then there'd be no need for ? in the url, etc. """ skins = self.getSkinList() realm = self.realm() filename = self._getFilename() if (filename in ('/tools/popup_monitor','/aptilopages/bye')) and \ (macroFile == 'pagelayout'): macroFile = 'pagelayoutmini' if macroFile: macroFile = '/' + macroFile if not macro: macro = '' else: macro = '/macros/%s' % macro skinnedFilename = realm + '/skins/' + r'%s' + macroFile + macro for skin in skins: try: skinned = os.path.normpath(skinnedFilename % skin) return self.restrictedTraverse(skinned) except KeyError,detail: pass raise (The above does a bit more than you need, but the guts of it is the restrictedTraverse call for the skinned filename. _getFilename just returns the base name of the page being viewed.) This gets referred to in ptl as: <metal:block use-macro="python:here.getMacro('line_render')"> KJL
[...]
Now, I would like to generate this sequence of alternative paths by a Python script to have full flexibility. Therefore I tried the following approach:
Create a Python "getMacroPath" script that takes the parameter "macroname" and looks like this: return 'here/content_macro_main.html/macros/' + macroname
(Of course, the script will finally generate many paths separated by "|")
In the ZOPE Page Template mydoc.html I use: <span tal:omit-tag="" tal:define="macropath python:here.getMacroPath('main')"> <span metal:use-macro="here/?macropath"> <!-- main slot --> <H2>Welcome</H2> <P>We welcome you to our website.</P> </span> </span>
The expansion of the'macropath' variable does not lead to something You want to have. If I would be a TALES-interpreter, I would read something approximately like: metal:use-macro="here/here/content_macro_main.html/macros/main" and as 'here' does not have such a thing like 'here/content_macro_main.html/macros/main', this generates the error message below. Instead You could pass the string returned by the script through the "path(...)" helper function, which returns what You want. The following snippet works at least for me: <span tal:omit-tag="" tal:define="macropath python:path(here.getMacroPath('main'))" > <span metal:use-macro="macropath"/> </span> hope it works for You, too ;) Cheers, Clemens
The Python script seems to work correctly, but ZOPE complains with the error: Error Type: KeyError Error Value: here/content_macro_main.html/macros/main
However, I don't see why METAL and/or ZOPE cannot deal with a TAL variable that has the correct value when it can deal with the same value as a string itself. Any ideas?
Regards,
Thomas Duebendorfer
_______________________________________________ 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 )
Thomas Duebendorfer writes:
I am looking for a flexible way to define the path for a macro to be used.
The following works: <span metal:use-macro="here/content_macro_main.html/macros/main | here/content_macros.html/macros/main | here/content_macros.html/macros/no_main_content"> .... Now, I would like to generate this sequence of alternative paths by a Python script to have full flexibility. Therefore I tried the following approach:
Create a Python "getMacroPath" script that takes the parameter "macroname" and looks like this: return 'here/content_macro_main.html/macros/' + macroname Thus, your script returns a string (representing a path expression) and you want to get the designated object.
The "path" function does this: it take a string and evaluates it as a path. Use: "python: path(here.getMacroPath(...))" Dieter
participants (4)
-
Clemens Robbenhaar -
Dieter Maurer -
KevinL -
Thomas Duebendorfer