chameleon icon indicating copy to clipboard operation
chameleon copied to clipboard

Cannot access repeat variable when iterating over dict items

Open bennuttall opened this issue 2 years ago • 1 comments

To iterate over a list, you can access the repeat variable by referencing the iteration item variable name:

<div tal:repeat="item range(10)">
  <p tal:condition="repeat.item.even">Even</p>
  <p tal:condition="repeat.item.odd">Odd</p>
</div>

However it doesn't seem possible to access the repeat variable when iterating over dict items:

<div tal:repeat="(key, value) my_dict.items()">
  <p tal:condition="repeat.key.even">Even</p>
  <p tal:condition="repeat.key.odd">Odd</p>
</div>

Essence of the traceback:

...
KeyError: 'end'

During handling of the above exception, another exception occurred:

...
AttributeError: end

During handling of the above exception, another exception occurred:

...
AttributeError: end

bennuttall avatar May 13 '22 12:05 bennuttall

This can be solved by unpacking in a separate tal:define:

<div tal:repeat="item my_dict.items()">
  <span tal:define="(key, value) item" tal:omit-tag="True">
    <p tal:condition="repeat.item.even">Even</p>
    <p tal:condition="repeat.item.odd">Odd</p>
  </span>
</div>

But still, is there (or could there be) a better way?

bennuttall avatar May 13 '22 12:05 bennuttall

Maybe this is relevant - https://stackoverflow.com/questions/56758190/chameleon-tal-zpt-template-problem-in-talrepeat ?

bapcyk avatar Apr 12 '23 17:04 bapcyk

@bennuttall you actually can access the repeat variable, but it's named differently.

Instead of repeat.key, you must use repeat['key', 'value'].

This is perhaps not the best ergonomics, but the reasoning is that you can iterate (repeat) over anything. It just so happens that the items() method yields a 2-tuple, but it could be something different.

See the test case for further reference.

malthe avatar Dec 08 '23 13:12 malthe