On Jan 11, 2013, at 9:56 AM, Jens Stimpfle wrote:
> Hi,
>
> I've spent some time on the docs, but I fail to see how I would do the
> following nicely in Mako: Define a menu structure with tags, and have it
> construct HTML menus given (preferably exchangeable) tag definitions.
>
> The input should look something like
>
> <%submenu path="pflanzen">
> <%menuitem path="index.html">
> <%submenu path="moose">
> <%submenu path="lebermoose">
> <%menuitem path="brunnenlebermoos.html"/>
> </%submenu>
> <%submenu path="laubmoose">
> <%menuitem path="torfmoos.html"/>
> </%submenu>
> <%submenu path="hornmoose">
> <%menuitem path="glattes_hornmoos.html"/>
> </%submenu>
> </%submenu>
>
> <%submenu path="Gefäßfplanzen">
> <%menuitem path="gemeine_kiefer.html"/>
> </%submenu>
> </%submenu>
>
> Now I'd like to define %submenu and %menuitem so that they can access
> their parents' environments. In particular, each tag should construct
> its own path, e.g. pflanzen/moose/lebermoose/brunnenlebermoos.html.
> But that's exactly what I fail at.
>
> The only workaround I see is to define the tags so they create global
> python values (something like self.attr.menustructure,
> self.attr.currentdir), but I'd rather have them directly translate into
> HTML.
there's an explicit way to do it, but you probably won't want to use it in this context since it is too verbose - the tags accept an argument called "args" that's used to pass data into the body callable, you can re-send this to the enclosing tag:
<%def name="submenu(path, parent=None)">
<submenu path="${parent or ''}/${path}">
${caller.body(path=path)}
</submenu>
</%def>
<%def name="menuitem(path, parent=None)">
<menu path="${parent or ''}/${path}">${caller.body(path=path)}</menu>
</%def>
<%self:submenu path="pflanzen" args="path">
<%self:menuitem path="index.html" parent="${path}" args="path"/>
</%self:submenu>
the other way is to just establish a nesting context somewhere as you are doing. When I do form libraries I typically hang some attributes like this off of the Pylons' "c." object, or some analogue. It is just a stack after all so it's safe to set up/tear down as your tags render. I hadn't thought of using self.attr, actually, but that object is local to current run of that template so should be OK.