[Zope] Tal:condition problem

KevinL darius@obsidian.com.au
21 Aug 2002 10:51:42 +1000


On Wed, 2002-08-21 at 02:15, Chris Withers wrote:
> Paul Winkler wrote:
> > So you can't do use-macro foo  where foo is some complex path?
> 
> Yeah, you can...
> 
> If you can't, what error do you get?
> 
> Chris 

Snippet:

<span tal:define="macroName
string:here/lib/${request/skin}/macros/${request/formname}">
  <metal:block use-macro="?macroName">
  </metal:block>
</span>

Doesn't work.  Neither does munging things around to make the use-macro
something like "here/?macroName".

Now ok, in this instance, you can replace the individual elements with
?skin and ?formname in the use-macro itself - but where the path is the
result of something more complex (like a python call for multiple
elements), it gets more awkward quickly - essentially, ifaics, you have
to pull the whole path out to python, rather than just bits of it, and
return the actual macro, rather than the path to the macro.

The case that started this can be rewritten, with a bit of care and some
reshuffling of variable names, to look something like:

<metal:block use-macro="container/?id/macros/?id">
</metal:block>

...no tal:conditions or repeating of blocks needed.  That requires,
however, that "id" in the form be changed to be equal to both the
filename and the macroname within the file.  Incidentally, if id
resolves to an empty string, you'll get errors from the metal code - I
think it's trying to slice the empty string in bad ways.  Anyway, the
original case doesn't suffer from this problem, I was just being overly
focussed on what I was battling with elsewhere ;)

What I'd like to be able to do, and what I was noting in my email that
you can't do, is go:

<span tal:define="macroName blah/de/blah/blah">
  <metal:block use-macro="here/?macroName">
  </metal:block>
</span>

That, imnsho, would be really useful.  At least for us ;)  We have a
situation where we have here/skins/?skin/?subSkin/pagelayout/macros/std
- but the skin, and particularly the subskin, folders don't always
exist.  For skin, we can easily figure it out, but then we have to call
something and tell it which skin we're in, and ask it to work out which
subSkin to use - and you can't return a blank string, 'cause metal gets
upset.  Ideally, we'd have one method that returns the /?skin/?subSkin
section (as there's more than just the pagelayout file in there), and
refer to use-macro="here/${here/getSkinDir}/pagelayout/macros/std" -
where getSkinDir resolves to either /skin or /skin/subSkin, as it needs
to (at which point, we also gain arbitrary levels of inheriting skins,
which is kinda cute).

What we've ended up doing is moving the choice of page and macro out to
a python method that returns the actual macro.  My problem with this is
we then need a tal python call, or we need a separate method for each
file we may want skinned - either "here/getPagelayout" (and all other
files), or "python:here.getSkinned('pagelayout')".  I like the first, I
dislike the second - trying to explain the shift from / to . to people
who don't know or want to know python but are familiar with html/xml, is
just another stumbling block/source of errors.  Ideally, we could refer
to use-macro="here/${here/getSkinDir}/pagelayout/macros/std" and have
getSkinDir give us back multiple path elements.

KJL