[Zope] Flexible path generation for metal:use-macro with Python (KeyError)

KevinL darius@obsidian.com.au
04 Dec 2002 11:03:10 +1100


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