-
-
Save getify/3696453 to your computer and use it in GitHub Desktop.
{ | |
"settings" : { | |
"foo" : "low", | |
"bar" : "high", | |
"baz" : "low" | |
} | |
} |
<!-- | |
NOTE: see this comment for clarification of why this | |
scenario is structured this way intentionally: | |
https://gist.github.com/3696453#gistcomment-570903 | |
Scenario: | |
Given the data structure above in "1.json", how would you | |
use a templating engine to generate this snippet of html | |
as a string? NOTE: the spirit of this question is to | |
generate a string of markup with a template engine, NOT | |
to do DOM manipulation. Imagine needing to generate this | |
kind of markup server-side to send over the wire. | |
--> | |
<h1>Settings</h1> | |
<h2>foo</h2> | |
<input type="radio" name="foo" value="low" checked> low | |
<input type="radio" name="foo" value="high"> high | |
<h2>bar</h2> | |
<input type="radio" name="bar" value="low"> low | |
<input type="radio" name="bar" value="high" checked> high | |
<h2>baz</h2> | |
<input type="radio" name="baz" value="low" checked> low | |
<input type="radio" name="baz" value="high"> high | |
here's how "grips" template engine would handle this scenario: | |
https://gist.github.com/3706912 |
doT.js
{{##def.radiogroup:
<h2>{{! name}}</h2>
{{~['low', 'high'] :value}}
<input type="radio" name="{{! name }}" value="{{= value }}"{{? it.settings[name] == value }} checked="checked"{{?}}/>
{{~}}
#}}
{{##def.settings:
<h1>Settings</h1>
{{~Object.keys(it.settings) :name}}
{{#def.radiogroup}}
{{~}}
#}}
{{#def.settings}}
doT.js (cleaned up a bit)
{{##def.radiogroup:
<h2>{{= name}}</h2>
{{~['low', 'high'] :value}}
<input type="radio" name="{{= name }}" value="{{= value }}"{{? it.settings[name] == value }} checked="checked"{{?}}/>
{{~}}
#}}
{{##def.settings:
<h1>Settings</h1>
{{~Object.keys(it.settings) :name}}
{{#def.radiogroup}}
{{~}}
#}}
{{#def.settings}}
Here's one approach you can use with JsRender: https://gist.github.com/3730412
UPDATE: The gist has been deleted. It is very easy to do in JsRender using the {{props}} tag
thanks @BorisMoore!
As requested, here's the solution for Raptor Templates. The below template will produce the exact output (less extra whitespace):
<c:template xmlns:c="core" params="settings">
<h1>Settings</h1>
<c:for each="(name,value) in settings">
<h2>$name</h2>
<c:for each="option in ['low', 'high']">
<input type="radio"
name="$name"
value="$option"
checked="${value === option ? null : undefined}" />
$option
</c:for>
</c:for>
</c:template>
Admittedly, it is a little odd to use "null" as the value for attributes that do not have a value in the resulting HTML, but it works. However, I prefer to to output checked="checked" at the expense of a few extra bytes since it's cleaner in my implementation and it still produces valid HTML:
<c:template xmlns:c="core" params="settings">
<h1>Settings</h1>
<c:for each="(name,value) in settings">
<h2>$name</h2>
<c:for each="option in ['low', 'high']">
<input type="radio"
name="$name"
value="$option"
checked="{?value === option;checked}" />
$option
</c:for>
</c:for>
</c:template>
You can easily try out the templates online at http://raptorjs.org/raptor-templates/try-online/
Let me know what you think.
Thanks,
Patrick
For reference, I created a Gist that shows the input Raptor template, the generated HTML and the compiled template:
https://gist.github.com/3966647
--Patrick
Thanks so much Patrick! Very much appreciate the input for Raptor. :)
Then the template doesn't work. I try to avoid that :-) I have a hard time thinking of a time that happened to me in JSP (or JavaScript for that matter) any time recently (or not-so-recently even). Generally I use pretty good names (not huge javaProgrammerApproved names but good ones), so that I can stay sane, so unless I've got a list of things with the same sort of thing inside it's pretty easy to keep the names straight. Heck even with a nested loop for a table, I can at least use "row" and "col".