Iteration on multiple nodes?

8 views
Skip to first unread message

beejamin

unread,
Dec 15, 2009, 9:51:04 PM12/15/09
to JavaScript Templates Engine PURE
Hi,

I'm just getting started with PURE, but so far it's been a pretty
smooth experience.

One thing I can't see is the ability to iterate over multiple target
nodes. The specific example here is producing a definition list: Each
iteration should produce 2 sibling nodes like so:

data =
[
{name:'term1', value: 'definition1'},
{name:'term2', value: 'definition2'}
];

template =
<dl class="attributes">
<dt class="name"></dt>
<dt class="value"></dt>
</dl>

desired result:
<dl class="attributes">
<dt class="name">term1</dt>
<dt class="value">definition1</dt>
<dt class="name">term2</dt>
<dt class="value">definition2</dt>
</dl>

It seems like the iteration targeting is simple if you're selecting a
single node which 'wraps' the nodes you want to work with, and you're
happy to duplicate that wrapper node on each iteration. I have tried
selectors like: 'dl.attributes > *' to iterate all children of the DL,
but that feels bad, and doesn't work at first glance anyway.

Can anyone help me with a directive to achieve this? I'm off to look
at function() directives, but I'm hoping there's an easier way.

Thanks in advance!

Mic Cvilic

unread,
Dec 16, 2009, 3:01:44 AM12/16/09
to pure-unobtrusive...@googlegroups.com
You can only iterate on a node, not a group of node.
As you guessed you need a directive for that.

Here's a solution: http://gist.github.com/257675
> --
>
> You received this message because you are subscribed to the Google Groups "JavaScript Templates Engine PURE" group.
> To post to this group, send email to Pure-Unobtrusive...@googlegroups.com.
> To unsubscribe from this group, send email to Pure-Unobtrusive-Rende...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/Pure-Unobtrusive-Rendering-Engine?hl=en.
>
>
>

beejamin

unread,
Dec 16, 2009, 2:52:53 PM12/16/09
to JavaScript Templates Engine PURE
Excellent - thanks Mic!

I hadn't thought of appending the new node - though I think I'll end
up prepending the DT before the DD, because I need more complex
structure within the DD, while the DT remains simple.

Out of curiosity, I assume this could be done, without putting
template structure into the directives, with a function directive.
Have you got any pointers there?

Thanks again for your help,

Ben

beejamin

unread,
Dec 16, 2009, 3:41:38 PM12/16/09
to JavaScript Templates Engine PURE
Hmm - does the '+' notation work differently when it is prepending
values? Your example works perfectly, but when I change it like so:

<dl>
<dd></dd>
</dl>

<script>
$('dl').render(
[
{name:'term1', value: 'definition1'},
{name:'term2', value: 'definition2'}
]
,{
dd:{
'term<-':{
'.':'term.value',
'+.':'<dt>#{term.name}</dt>'
}
}
});
</script>

The output is:

<dl>
<dd></dd>
<dt>term1</dt>
definition1
<dd></dd>
<dt>term2</dt>
definition2
</dl>

It looks like Append '.+' adds content after the node, while Prepend
'+.' adds content to the value (which is the behaviour I'd expect).
Could you clarify how this works?

Thanks again!

Mic Cvilic

unread,
Dec 16, 2009, 5:24:08 PM12/16/09
to pure-unobtrusive...@googlegroups.com
I thought the way to use the dl, dd, dt's could be:
<dl><dt><dd></dd></dt></dl>
And it's wrong: http://www.w3.org/TR/html401/struct/lists.html

I guess my example was luck(the browser reorganise the tags), while
yours is a reality check :|

The directive below works:
'term<-':{
'.':'#{term.name}<dt>#{term.value}</dt>'
}

This one not:
'term<-':{
'.':'<dt>#{term.value}</dt>#{term.name}'
}


Sorry for the mess with dd's
Here's a solution with dt's only:

<script>
$('dl').render(
[
{name:'term1', value: 'definition1'},
{name:'term2', value: 'definition2'}
]
,{
dt:{
'term<-':{
'.':'#{term.value}</dt><dt>#{term.name}'
}
}
});
</script>

beejamin

unread,
Dec 16, 2009, 7:30:37 PM12/16/09
to JavaScript Templates Engine PURE
Hi Mic,

I suspected the browser might be tidying up a bit - that makes sense,
thanks. I'm leaning towards a solution using sub-templates - because I
need to include more complex markup within the DT's, and I don't want
that going into the directives.

Can you tell me if .compile will accept multiple nodes, or only one?
I'm using jQuery, and would like to do something like the following to
produce a set of sub-template chunks:

$('.subTemplate').children().compile(directives);

where .subTemplate is something like:

<div class="subTemplate">
<dt></dt>
<dd></dd>
</div>

I can see that providing a collection like .children is pretty jQuery
specific, and not something you'd design for. Can you think of an easy
way to make that work? Is it possible to pass in .subTemplate, then
strip it out at compile time?

I'll have a dig around in pure - see if I can work out what's going on
in there. Any thoughts you can provide are much appreciated!

Cheers

Mic Cvilic

unread,
Dec 16, 2009, 8:02:05 PM12/16/09
to pure-unobtrusive...@googlegroups.com
Here's an example of using subtemplates: http://gist.github.com/250157
But with a twist, the subtemplate is the template itself, then starting
a recursion.
In your case you can compile various subtemplates and then call them
passing the full JSON data or a subset.

beejamin

unread,
Dec 17, 2009, 3:05:53 PM12/17/09
to JavaScript Templates Engine PURE
Thanks Mic - yep that's the subTemplating example I'm working with -
and it works perfectly, but I've run into the same problem again: I
want to use a pair of sibling nodes as a subTemplate - but the node
object requires a single parent node, and everything else (I was
thinking documentFragment) inherits from node.

I'm working on a 'wrapped' argument which will tell .compile() to
strip the outermost node out of the template - that should do the job.
I'll try to implement it as a plugin so you can have a look.

Thanks again - I'm really enjoying working with PURE.

Reply all
Reply to author
Forward
0 new messages