As you mentioned, repeating elements is pretty clunky in Pymeld. I came up with several starkly similar schemes like this and they were one of the primary reasons I gave up on my ideas years ago. However, I think I might have a solution. The solution assumes that you have an existing "template" element that you want to repeat (it may contain child elements), and that you wish to replace it with zero or more copies populated with data or otherwise munged.
Having to clone, modify and insert each element manually is too tedious. Imagine, however that each element in the template has a method 'zip_repeat(iterable)'. When called this method returns a generator which first removes the template element from the document, then yields tuples of '(element.clone(), iterable.next())'. Each time a cloned element is yielded, it is inserted in the document right after the last element (the first element is inserted where the original element was). The result is similar to "tal:repeat", especially if you iterate it in a for-loop. Here's an example. Here is a snippet of the document (for now we continue overloading the tag "id" for simplicity)::
Here is the python "transform" to populate it, imagine that we have loaded the above into a Template instance named "template". __getitem__() on Template objects returns the element with that id::
for tr, doc in template['doc_item'].zip_repeat(context.listFolderContents()):
tr['title'].content = doc.getTitle()
tr['description'].content = doc.getDescription()
So iterating zip_repeat() yields clones of the original table row preplaced in the DOM where you want it, along with each document in the folder so you can modify the row content or anything else you want. When rendered, it might look something like this::
Probably the biggest problem I see with this is that we have multiple tags with the same "id" value which is technically not allowed. So that's probably a vote for using a custom namespace for identifying elements used by templates. Either way the ids will probably need to be munged to keep thing unabiguous in cases where a pipeline of template "transforms" like above are employed.
Me likey
Posted byslinkpat
2005-11-06 10:41 PM
I talked a little about the id problem in my notes.
If zip_repeat() (or whatever) munges ids on elements it outputs, and we use a new namespace, and this namespace doesn't require globally unique ids, then I think we're fine.
Merged into my proposal
Posted byslinkpat
2005-11-07 12:34 PM
with credit, of course.
Updated text is still at: http://www.slinkp.com/code/zopestuff/templates
I also emailed a link to Richie at entrian, the PyMeld author.
Having to clone, modify and insert each element manually is too tedious. Imagine, however that each element in the template has a method 'zip_repeat(iterable)'. When called this method returns a generator which first removes the template element from the document, then yields tuples of '(element.clone(), iterable.next())'. Each time a cloned element is yielded, it is inserted in the document right after the last element (the first element is inserted where the original element was). The result is similar to "tal:repeat", especially if you iterate it in a for-loop. Here's an example. Here is a snippet of the document (for now we continue overloading the tag "id" for simplicity)::
<table>
<tr>
<th>Title</th>
<th>Description</th>
</tr>
<tr id="doc_item">
<td id="title">Document Title</td>
<td id="description">Document Description</td>
</tr>
</table>
Here is the python "transform" to populate it, imagine that we have loaded the above into a Template instance named "template". __getitem__() on Template objects returns the element with that id::
for tr, doc in template['doc_item'].zip_repeat(context.listFolderContents()):
tr['title'].content = doc.getTitle()
tr['description'].content = doc.getDescription()
So iterating zip_repeat() yields clones of the original table row preplaced in the DOM where you want it, along with each document in the folder so you can modify the row content or anything else you want. When rendered, it might look something like this::
<table>
<tr>
<th>Title</th>
<th>Description</th>
</tr>
<tr id="doc_item">
<td id="title">Foo Document</td>
<td id="description">The Document of Foo</td>
</tr>
<tr id="doc_item">
<td id="title">Bar Document</td>
<td id="description">The Document of Bar</td>
</tr>
<tr id="doc_item">
<td id="title">Baz Document</td>
<td id="description">The Document of Baz baby!</td>
</tr>
</table>
Probably the biggest problem I see with this is that we have multiple tags with the same "id" value which is technically not allowed. So that's probably a vote for using a custom namespace for identifying elements used by templates. Either way the ids will probably need to be munged to keep thing unabiguous in cases where a pipeline of template "transforms" like above are employed.
If zip_repeat() (or whatever) munges ids on elements it outputs, and we use a new namespace, and this namespace doesn't require globally unique ids, then I think we're fine.
Updated text is still at: http://www.slinkp.com/code/zopestuff/templates
I also emailed a link to Richie at entrian, the PyMeld author.