On Wed, Sep 01, 2004 at 04:38:30PM +0200, Johan Carlsson wrote:
Jim Penny wrote:
On Wed, 01 Sep 2004 14:45:19 +0200 Johan Carlsson <johanc@easypublisher.com> wrote:
Hi, I need help :-)
I'm trying to implement a new Widget for Archetypes. So I have to write TAL (not my favorite hobby).
Here's what I've settled for so far: vocab is the DisplayList derivative (item is a key).
<tal:loop repeat="item vocab"> <optgroup tal:attributes="label python:vocab.getValue(item);" tal:condition="python:vocab.isLabel(item)"> </optgroup> <option selected="" tal:condition="not:python:vocab.isLabel(item)" tal:attributes="value item; selected python:test(here.unicodeTestIn(item, value),
'selected', None);" tal:content="python: vocab.getValue(item)"/> </tal:loop>
This is a simple neting mistake, try: <tal:loop repeat="item vocab"> <optgroup tal:attributes="label python:vocab.getValue(item);" tal:condition="python:vocab.isLabel(item)"> <option selected="" tal:condition="not:python:vocab.isLabel(item)" tal:attributes="value item; selected python:test(here.unicodeTestIn(item, value), ' selected', None);" tal:content="python: vocab.getValue(item)"/> </optgroup> </tal:loop>
No. That would only return the <optgroup> because <option> is dependant on the optgroups condition (and it's condition is the negation of that so it will never appear).
Though, as a matter of taste, I don't like this approach, I suspect that it will be hard to maintain, as it depends on whatever is generating vocab to deliver values in a sorted order. To me it would be much more natural to use a nested loop paramterized on the label value to generate the options.
I agree. Also it's probably the only way to do it with TAL.
Actually it's kind of good because this way TAL forces me to write better logic.
The problem is that with the Archetypes DisplayList this gets really complicated to achieve. Not a TAL bad rather an Archetypes inflexibilty.
So, maybe write a Script that does some processing of the DisplayList and gives you something more reasonable. I gather that iterating over vocab and doing getValue() on each gives you something like: ['A', 'Ada', 'Ape', 'B', 'Banana', 'Buffy', ...] So, write a script that does something like (untested): items = {} raw = [vocab.getValue(item) for item in vocab] for s in raw: if vocab.isLabel(s): items[s].setdefault([]) else: items[s[0]].append(s) result = [{'label': k, 'values': v) for k, v in items] return result Then you should have something like this: [{'label: 'A', 'values': ('Ada', 'Ape')}, {'label: 'B', 'values': ('Banana', 'Buffy')}, ... ] Plugging this in to your template should then be easy. Something like: <tal:loop repeat="group myScript"> <optgroup tal:attributes="label group/label" <tal:loop repeat="item group/values"> <option selected="" tal:attributes="value item; selected python:test(here.unicodeTestIn(item, value), ' selected', None);" tal:content="item" /> </tal:loop> </optgroup> </tal:loop> ... except that I goofed up unicodeTestIn which apparently expects the original item from your vocab as an argument. Well, stuff that in your data structure somewhere too :-) -- Paul Winkler http://www.slinkp.com