Tal:repeat in templates.listing_tabular.pt

I have a dexterity field called dhhs_divisions. It is of type zope.schema.Choice

I am trying to list the items line by line in my collection table display and have the following codes in my product at browser/overrides/plone.app.contenttypes.browser.templates.listing_tabular.pt

Code 1:

<td tal:condition="python:field in ['dhhs_division']"
    tal:define="field_data python:view.tabular_fielddata(item, field)">
    <tal:block tal:repeat="div field_data" 
tal:content="field_data"/></td>

Result for three rows on the table:
{'value': set([u'Medical Assistance (DMA)', u'Health Service Regulation (DHSR)'])}
{'value': u'Social Services (DSS)'}
{'value': Missing.Value}

Code 2:

<td tal:condition="python:field in ['dhhs_division']"
      tal:define="field_data python:view.tabular_fielddata(item, field)">
       <tal:block tal:repeat="div field_data" 
                        tal:content="div"/></td>

Results for three rows on the table:
value
value
value

I am trying to list the results in the following manner:
Row 1: Medical Assistance (DMA)
Health Service Regulation (DHSR)
Row 2: Social Services (DSS)
Row 3: Blank

I am sure I am missing something. Any help would be most appreciated. Thank you.

possibly like that tal:content="div/value"

I tried it and got this error:

<td tal:condition="python:field in ['dhhs_division']"
     tal:define="field_data python:view.tabular_fielddata(item, field)">
     <tal:block tal:repeat="div field_data" 
                      tal:content="div/value"/>
</td>
Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module Products.Five.browser.metaconfigure, line 485, in __call__
  Module Products.Five.browser.pagetemplatefile, line 125, in __call__
  Module Products.Five.browser.pagetemplatefile, line 59, in __call__
  Module zope.pagetemplate.pagetemplate, line 137, in pt_render
  Module five.pt.engine, line 98, in __call__
  Module z3c.pt.pagetemplate, line 163, in render
  Module chameleon.zpt.template, line 261, in render
  Module chameleon.template, line 191, in render
  Module chameleon.template, line 171, in render
  Module 5e7d42b18f502568855d6349e62402b3.py, line 1548, in render
  Module 2ddb691e7f8b476bdac1352bb73fe831.py, line 1223, in render_master
  Module 2ddb691e7f8b476bdac1352bb73fe831.py, line 420, in render_content
  Module 5e7d42b18f502568855d6349e62402b3.py, line 1536, in __fill_content_core
  Module 5e7d42b18f502568855d6349e62402b3.py, line 101, in render_content_core
  Module 5e7d42b18f502568855d6349e62402b3.py, line 482, in render_listing
  Module 5e7d42b18f502568855d6349e62402b3.py, line 1267, in render_listitem
  Module five.pt.expressions, line 154, in __call__
  Module five.pt.expressions, line 126, in traverse
  Module zope.traversing.adapters, line 142, in traversePathElement
   - __traceback_info__: ('value', 'value')
  Module zope.traversing.adapters, line 56, in traverse
   - __traceback_info__: ('value', 'value', ())
LocationError: ('value', 'value')

 - Expression: "div/value"
 - Filename:   ... ne.app.contenttypes.browser.templates.listing_tabular.pt
 - Location:   (line 106: col 46)
 - Source:     tal:content="div/value"/>
                            ^^^^^^^^^
 - Arguments:  repeat: {...} (0)
               template: <ViewPageTemplateFile - at 0x7fae35741ad0>
               views: <ViewMapper - at 0x7fae3551c990>
               modules: <instance - at 0x7fae49f55638>
               args: <tuple - at 0x7fae522fa050>
               here: <ImplicitAcquisitionWrapper programs at 0x7fae3c0eedc0>
               user: <ImplicitAcquisitionWrapper - at 0x7fae3d921730>
               nothing: <NoneType - at 0x8f5320>
               container: <ImplicitAcquisitionWrapper programs at 0x7fae3c0eedc0>
               request: <instance - at 0x7fae37f2a7a0>
               wrapped_repeat: <SafeMapping - at 0x7fae3575ea48>
               traverse_subpath: <list - at 0x7fae372bdf80>
               default: <object - at 0x7fae52217540>
               loop: {...} (3)
               context: <ImplicitAcquisitionWrapper programs at 0x7fae3c0eedc0>
               view: <SimpleViewClass from /var/plone/sharedservices01/buildout-cache/eggs/plone.app.contenttypes-1.4.9-py2.7.egg/plone/app/contenttypes/browser/templates/listing_tabular.pt tabular_view at 0x7fae3551c490>
               translate: <function translate at 0x7fae356440c8>
               root: <ImplicitAcquisitionWrapper Zope at 0x7fae37fa53c0>
               options: {...} (0)
               target_language: <NoneType - at 0x8f5320>

When I tried this instead, I got better results:

<td tal:condition="python:field in ['dhhs_division']"
tal:define="field_data python:view.tabular_fielddata(item, field)">
<tal:block tal:repeat="div field_data" 
tal:content="field_data/value"/>
</td>

Row 1: set([u'Medical Assistance (DMA)', u'Health Service Regulation (DHSR)'])
Row 2: Social Services (DSS)
Row 3: Blank

However, I still can't pull out values from the dictionary for Row 1

Try this one (quick'n dirty :wink:

<td tal:condition="python:field in ['dhhs_division']"
    tal:define="field_data python:view.tabular_fielddata(item, field)">
<tal:block tal:repeat="k python:field_data.keys()">
    <tal:define="value python:field_data.get(k)">
        <tal:cond condition="value|nothing">
            <span tal:content="value">Value</span>
        </tal:cond>
    </tal:define>
</tal:block>
</td>

Thanks Michael. When I tried it, the following errors occured:

Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module Products.Five.browser.metaconfigure, line 485, in __call__
  Module Products.Five.browser.pagetemplatefile, line 125, in __call__
  Module Products.Five.browser.pagetemplatefile, line 59, in __call__
  Module zope.pagetemplate.pagetemplate, line 131, in pt_render
   - Warning: Compilation failed
   - Warning: chameleon.exc.ParseError: Unexpected end tag.

 - String:     "</tal:define>"

So I did the following:

<td tal:condition="python:field in ['dhhs_division']"
       tal:define="field_data python:view.tabular_fielddata(item, field)">
      <tal:block tal:repeat="k python:field_data.keys()">
           <tal:define tal:define="value python:field_data.get(k)">
             <tal:cond tal:condition="value|nothing">
                 <span tal:content="value">Value</span>
              </tal:cond>
            </tal:define>
        </tal:block>
 </td>

And got the same results as before:
Row 1: set([u’Medical Assistance (DMA)’, u’Health Service Regulation (DHSR)’])
Row 2: Social Services (DSS)
Row 3: Blank

Am I missing something?

Try:

<tal:cond tal:condition="value|nothing">
    <span tal:repeat="each_value value">
         ${each_value}
   </span>
</tal:cond>

PS:

 <span>${something}</span>

Is basically doing the same as:

<span tal:content="something">Something</span>

PS PS: The error that you got (Unexpected end tag ) is probably just a typo, most likely you forgot to close a tag

got it, it should be:

<tal:cond tal:condition=“value|nothing”>

Thanks Espen and mgraf. So this is what I did:

<td tal:condition="python:field in ['dhhs_division']"
       tal:define="field_data python:view.tabular_fielddata(item, field)">
      <tal:block tal:repeat="k python:field_data.keys()">
           <tal:define tal:define="value python:field_data.get(k)">
             <tal:cond tal:condition="value|nothing">
                <span tal:repeat="each_value value">
                  ${each_value}
                </span>
              </tal:cond>
            </tal:define>
        </tal:block>
 </td>

The result is rather weird. It looks like the items are read character by character instead of item by item:
Row 1: Medical Assistance (DMA) Health Service Regulation (DHSR)
Row 2: S o c i a l S e r v i c e s ( D S S ) (there is a space between each letter except when a space is needed)

Please advise. Thank you.

If fact, it is not weird, it is 'normal behavior'.

I did not read your post properly, so I did not notice that you had a set for the first and a string for the next (I thought you had a set or list with just one item in it).

I am not sure about what is the best approach, somebody else needs to answer …

I am just guessing: Maybe you can do a check to see if the field is a set or a string (if set or list, do the repeat loop), or you could save the others as sets or list ( any chance that they will have multiple values in the future ??)

Maybe this ? it's very ugly anyway :slight_smile:

<td tal:condition="python:field in ['dhhs_division']"
       tal:define="field_data python:view.tabular_fielddata(item, field)">
      <tal:block tal:repeat="k python:field_data.keys()">
           <tal:define tal:define="value python:'\n'.join(field_data.get(k)) if isinstance(field_data.get(k), set) else field_data.get(k)">
             <tal:cond tal:condition="value|nothing">
                 <span tal:content="value">Value</span>
              </tal:cond>
            </tal:define>
        </tal:block>
 </td>

should work, but if you need to style each entry (for example with an icon) or translate it will not work

Espen, field_data shows up in the following way:
{‘value’: set([u’Medical Assistance (DMA)’, u’Health Service Regulation (DHSR)’])}
{‘value’: u’Social Services (DSS)’}
{‘value’: Missing.Value}
Would you consider this a set of strings?

So I tried the above the following errors came out:

Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module Products.Five.browser.metaconfigure, line 485, in __call__
  Module Products.Five.browser.pagetemplatefile, line 125, in __call__
  Module Products.Five.browser.pagetemplatefile, line 59, in __call__
  Module zope.pagetemplate.pagetemplate, line 137, in pt_render
  Module five.pt.engine, line 98, in __call__
  Module z3c.pt.pagetemplate, line 163, in render
  Module chameleon.zpt.template, line 261, in render
  Module chameleon.template, line 191, in render
  Module chameleon.template, line 171, in render
  Module 8f5eeabbac0ea26a583cf37f06a191c8.py, line 1612, in render
  Module 2ddb691e7f8b476bdac1352bb73fe831.py, line 1223, in render_master
  Module 2ddb691e7f8b476bdac1352bb73fe831.py, line 420, in render_content
  Module 8f5eeabbac0ea26a583cf37f06a191c8.py, line 1600, in __fill_content_core
  Module 8f5eeabbac0ea26a583cf37f06a191c8.py, line 104, in render_content_core
  Module 8f5eeabbac0ea26a583cf37f06a191c8.py, line 485, in render_listing
  Module 8f5eeabbac0ea26a583cf37f06a191c8.py, line 1231, in render_listitem
  Module chameleon.utils, line 406, in __getitem__
NameError: each_value

 - Expression: "td tal:condition="python:field in ['dhhs_division']"
       tal:define="field_data python:view.tabular_fielddata(item, field)">
      <tal:block tal:repeat="k python:field_data.keys()">
           <tal:define tal:define="value python:field_data.get(k)">
             <tal:cond tal:condition="value|nothing">
                <span tal:repeat="each_value value">
                  ${each_value}
                </span>
              </tal:cond>
            </tal:define>
        </tal:block>
 </td"
 - Filename:   ... ne.app.contenttypes.browser.templates.listing_tabular.pt
 - Location:   (line 103: col 4)
 - Source:     ... td tal:condition="python:field in ['dhhs_division']"
                   ^
 - Arguments:  repeat: {...} (0)
               template: <ViewPageTemplateFile - at 0x7f7544db8650>
               views: <ViewMapper - at 0x7f7544eaf7d0>
               modules: <instance - at 0x7f7558173638>
               args: <tuple - at 0x7f7560518050>
               here: <ImplicitAcquisitionWrapper programs at 0x7f754c342b90>
               user: <ImplicitAcquisitionWrapper - at 0x7f754c336410>
               nothing: <NoneType - at 0x8f5320>
               container: <ImplicitAcquisitionWrapper programs at 0x7f754c342b90>
               request: <instance - at 0x7f7547735128>
               wrapped_repeat: <SafeMapping - at 0x7f75452d2578>
               traverse_subpath: <list - at 0x7f7545bd5e18>
               default: <object - at 0x7f7560435540>
               loop: {...} (2)
               context: <ImplicitAcquisitionWrapper programs at 0x7f754c342b90>
               view: <SimpleViewClass from /var/plone/sharedservices01/buildout-cache/eggs/plone.app.contenttypes-1.4.9-py2.7.egg/plone/app/contenttypes/browser/templates/listing_tabular.pt tabular_view at 0x7f75450a8090>
               translate: <function translate at 0x7f7544c30d70>
               root: <ImplicitAcquisitionWrapper Zope at 0x7f754c145aa0>
               options: {...} (0)
               target_language: <NoneType - at 0x8f5320>

I was baffled a minute by this 'each_value' but it seems to come from an earlier answer, that you probably mixed in with my proposal, while I was refering to your own post

You are right, gp54321. Thanks so much! Commenting out the older codes did not do it. I have to delete them all together. Don't know why but once I got that done, the error went away. So using your codes:

<td tal:condition="python:field in ['dhhs_division']"
       tal:define="field_data python:view.tabular_fielddata(item, field)">
      <tal:block tal:repeat="k python:field_data.keys()">
           <tal:define tal:define="value python:'\n'.join(field_data.get(k)) if isinstance(field_data.get(k), set) else field_data.get(k)">
             <tal:cond tal:condition="value|nothing">
                 <span tal:content="value">Value</span>
              </tal:cond>
            </tal:define>
        </tal:block>
 </td>

This is what I got:
Row 1: Medical Assistance (DMA) Health Service Regulation (DHSR)
Row 2: Social Services (DSS)
Row 3: Blank

One more question. For Row 1, is there a possibility to put Medical Assistance (DMA) and Health Service Regulation (DHSR) on separate lines?
Medical Assistance (DMA)
Health Service Regulation (DHSR)

untested:

value python:'<br/>'.join(field_data.get(k)) if isinstance(field_data.get(k), set) else field_data.get(k)">

it's too simple I think.
It should be possible to do a tal:condition on isinstance and nest loops but I'm afraid that it is beyond my skills to get it right quickly without having some test data available.

Yes, I have tried it before and it turned out in the following way:

<tal:define tal:define="value python:'<br />'.join(field_data.get(k)) if isinstance(field_data.get(k), set) else field_data.get(k)">

Medical Assistance (DMA)<br />Health Service Regulation (DHSR)

I think that Chameleon escapes your HTML codes when it's done this way.