<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Aug 23, 2011, at 8:34 AM, Florian Lindner wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hello,<br><br>I'm still trying to figure out what is the correct way to render data in a <br>template that comes from a list, e.g. to produce a table.<br><br>I have figured out a way, but I got no idea if that's the way to go:<br><br> &nbsp;&nbsp;&nbsp;&lt;table&gt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr t:render="table_row"&gt;&lt;td&gt;&lt;t:slot name="table_content" /&gt;&lt;/td&gt;&lt;/tr&gt;<br> &nbsp;&nbsp;&nbsp;&lt;/table&gt;<br><br>with that renderer:<br><br> &nbsp;&nbsp;&nbsp;@renderer<br> &nbsp;&nbsp;&nbsp;def table_row(self, request, tag):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows = ["A", "B", "C"]<br><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output_list = []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for row in rows:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t = tag.clone()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.fillSlots(table_content=row)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output_list.append(t)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return output_list<br><br>Is that how it should be done in twisted templating?</div></blockquote><br></div><div>This is pretty close to the way I've been doing it, which is:</div><div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>@renderer</div><div>def table_row(self, request, tag):</div><div>&nbsp; &nbsp; rows = ['A', 'B', 'C']</div><div>&nbsp; &nbsp; for row in rows:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; yield tag.clone().fillSlots(table_content=row)</div></blockquote><div><br></div><div>The logic is basically the same, it is just a little bit shorter. &nbsp;Sometimes I will also include a 'hasRows' and 'noRows' renderers in the outer template, like:</div><div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>&lt;table t:render="hasRows"&gt;</div><div><div><div>&lt;tr t:render="table_row"&gt;&lt;td&gt;&lt;t:slot name="table_content" /&gt;&lt;/td&gt;&lt;/tr&gt;</div></div></div><div>&lt;/table&gt;</div><div><br></div><div>&lt;div t:render="noRows"&gt;</div><div>No rows.</div><div>&lt;/div&gt;</div></blockquote><div><br></div><div>The renderers for these just look like this:</div><div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>@renderer</div><div>def hasRows(self, request, tag):</div><div>&nbsp; &nbsp; rows = ...</div><div>&nbsp; &nbsp; if not rows:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return ''</div><div>&nbsp; &nbsp; return tag</div></blockquote><div><br></div><div>Fans of nevow's 'pattern' feature will be quick to point out that this is one of the use-cases for patterns, and indeed, so far I have had to write some logic to cache 'rows' on 'self', and a few redundant renderers which would have been unnecessary if we had patterns. &nbsp;But I actually find templates like this easier to read, and it saves me from having to use &lt;t:transparent&gt;s that hold the table and the div in the same renderer, which makes my browser ever so slightly happier to view the template un-rendered. &nbsp;I think I'll probably add some utilities for doing these things automatically, once I have a little more experience with this new, simplified templating style :).</div><div><br></div><div>Hope this was a helpful insight into some real-world t.w.t usage :).</div><div><br></div><div>-glyph</div></body></html>