Handling table header in a list widget in a view template

This code looks for all tiddlers where the current tiddler appears in the category field and prints out a list sorted on ‘republish1’ and ‘published-on’:

<$vars sub=[get[republish1]else{!!published-on}]>
  <$list filter="[all[tiddlers]contains:category<currentTiddler>!sortsub:date<sub>]">
    <$link /> -- {{!!published-on}} -- {{!!republish1}} <br>
  </$list>
</$vars>

If the current tiddler does not appear in the category field of any other tiddler, nothing happens. So, this code resides in my view template without causing any problem.

I wanted to convert this simple list into a table. The question was, where do I put the table header? If I put it after the $list, it will create a header above every row. If I put it before the $list, the table header will appear in every tiddler!

How do I solve this problem?

If I put it before the $list, the table header will appear in every tiddler!

That is not correct!

<table>
<tr><th>col 1</th><th>col 2</th></tr>
<$list ...
   <tr><td><$link /></td><td><$link /></td></tr>
</$list>
</table>

You could even use a list both in the heading , and the rows to iterate the columns.

You can use two $list widgets, one to test to see if the table is to be shown, and another to actually generate the rows of the table:

<$list filter="[all[tiddlers]contains:category<currentTiddler>limit[1]]" variable="has_matching_category">
   <table>
      <tr><th>item</th><th>published</th><th>republished</th></tr>
      <$vars sub="[get[republish1]else{!!published-on}]">
      <$list filter="[all[tiddlers]contains:category<currentTiddler>!sortsub:date<sub>]">
         <tr><td><$link/></td><td>{{!!published-on}}</td><td>{{!!republish1}}</td></tr>
      </$list>
      </$vars>
   </table>
</$list>

Notes:

  • The outer $list tests to see if there are any tiddlers whose “category” field contains the current tiddler title
  • limit[1] is added to the outer $list filter so that the table is only displayed once, regardless of how many tiddlers match the filter
  • !sortsub:date<sub> is omitted from the outer $list filter since it only matters that there are matching tiddlers and, for the purposes of this “test filter”, it doesn’t matter what order they are in.
  • variable="has_matching_category" is used to prevent the outer $list from changing the value of currentTiddler so it can be used by the inner $list filter
  • Then, the table header row is output, followed by the inner $list, which gets all of the matching tiddlers, sorted in the desired way, and outputs a table row for each tiddler.

enjoy,
-e

@EricShulman Thanks a lot. That did solve the problem. And your excellent explanation also made me understand how it got solved.