Skip to content

Instantly share code, notes, and snippets.

@getify
Created September 12, 2012 14:19
Show Gist options
  • Save getify/3706912 to your computer and use it in GitHub Desktop.
Save getify/3706912 to your computer and use it in GitHub Desktop.
how "grips" templating handles it, in response to https://gist.github.com/3696453
{$: '#settings' }
<h1>Settings</h1>
{$* $.settings | name = _.key | options['low','high'] = _.value ? "checked" }
<h2>{$= name $}</h2>
{$* options }
<input type="radio" name="{$= name $}" value="{$= _.key $}" {$= _.value $}> {$= _.key $}
{$}
{$}
{$}
<!--
Here's how "grips" templating engine would handle it.
Some notes:
1. Some of the "grips" template tag syntax shown in this example:
- `{$: "#id" }` defines a top-level template section by id.
- `{$* ref }` defines a loop block to iterate over `ref`.
- `{$= ref $}` includes the value of `ref`.
- for define tags and loop tags, you can optionally have a | delimited
list of assignment statements. (see `name` and `setting` assignments above)
- any reference of a variable that is not scoped (prefixed) with `$.` or
`_.` will automatically be treated as a "local variable" within that
block. you can create local variables as much as necessary. (see `name`
and `setting` variables above)
- assignments can optionally use a ?: ternary operator. A special syntax
applies to the else clause: an empty string ("") expression is assumed if the
else clause (`: ref`) is omitted.
- a special syntax for assignment statements is when the LH of the assignment
includes a set literal (like `checked['low','high'] = ...`), and the RH of
the assignment is a ?: ternary expression. The example above
(`checked['low','high'] = setting ? 'checked'`) roughly equates to:
`checked['low'] = (setting === 'low') ? 'checked' : ''` and
`checked['high'] = (setting === 'high') ? 'checked' : ''`. It basically is
a pre-computation hash for the comparisons, where the comparison results can
then be used in the template as an include. Since the conditional comparison
has already happened before you include, it emulates the concept of a
conditional include.
2. in expressions, `$` is how you reference the data structure in the current
context.
3. in expressions, `_` is how you reference the current iterator in a loop.
- `_.value` is the actual value of the current iteration (whatever data
type it may be).
- `_.key` is either the numeric index for an array iteration, or the string
property name for an object-property iteration.
- `_.index` is the numeric index of the iteration (regardless of whether
iterating over an array or object).
- `_.even` is true for even (0,2,4,...) iterations.
- `_.odd` is true for odd (1,3,5,...) iterations (iterations are 0-based).
4. Loops can iterate over arrays, objects, set literals (`['low','high']` as shown
above), or range literals (which would look like `[3..7]`).
-->
(function __3_html__(G) {
function __sort_fn__(a, b) {
return a - b;
}
var partial = G.definePartial,
clone = G.cloneObj,
extend = G.extend,
esc = G.strEscapes,
error = G.error,
unerr = new Error("Unknown error"),
RLH = G.RangeLiteralHash,
cID = "3.html";
partial(function __settings__($, $$) {
$ = $ || {};
$$ = clone($$) || {};
var i, ret = "",
ret2, _;
ret += "\n <h1>Settings</h1>\n ";
ret2 = (function __loop__() {
function __iter__($, $$, value, key, index) {
var i, ret = "",
ret2, _;
if (value == null) return ret;
$$ = clone($$);
_ = {
value: value,
key: key,
index: index,
even: (index % 2) === 0,
odd: (index % 2) === 1,
first: (index === 0),
last: (index === len - 1)
};
try {
$$.name = _.key;
} catch (err1) {
return error(cID, {
"type": 11,
"pos": {
"line": 3,
"col": 21
},
"val": "name = _.key"
}, "Assignment failed in loop iteration: " + JSON.stringify(_, ["key", "index"]), err1);
}
try {
$$.options = {};
var _set = ['low', 'high'];
for (i = 0; i < 2; i++) {
$$.options[_set[i]] = (_.value === _set[i]) ? "checked" : "";
}
} catch (err2) {
return error(cID, {
"type": 11,
"pos": {
"line": 3,
"col": 36
},
"val": "options['low','high'] = _.value ? \"checked\" : \"\""
}, "Assignment failed in loop iteration: " + JSON.stringify(_, ["key", "index"]), err2);
}
ret += "\n <h2>";
try {
ret += $$.name;
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 4,
"col": 16
},
"val": "name"
}, "Insert reference failed", err);
}
ret += "</h2>\n ";
ret2 = (function __loop__() {
function __iter__($, $$, value, key, index) {
var i, ret = "",
ret2, _;
if (value == null) return ret;
$$ = clone($$);
_ = {
value: value,
key: key,
index: index,
even: (index % 2) === 0,
odd: (index % 2) === 1,
first: (index === 0),
last: (index === len - 1)
};
ret += "\n <input type=\"radio\" name=\"";
try {
ret += $$.name;
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 6,
"col": 42
},
"val": "name"
}, "Insert reference failed", err);
}
ret += "\" value=\"";
try {
ret += _.key;
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 6,
"col": 62
},
"val": "_.key"
}, "Insert reference failed", err);
}
ret += "\" ";
try {
ret += _.value;
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 6,
"col": 76
},
"val": "_.value"
}, "Insert reference failed", err);
}
ret += "> ";
try {
ret += _.key;
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 6,
"col": 92
},
"val": "_.key"
}, "Insert reference failed", err);
}
ret += "\n ";
return ret;
}
var i, j = 0,
len, ret = "",
it, tmp;
try {
it = $$.options;
if (it == null) {
return "";
}
if (Object.prototype.toString.call(it) === "[object Array]") {
len = it.length;
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[i], "" + i, i);
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
}
} else if (typeof it === "object") {
tmp = Object.keys(it);
len = tmp.length;
if (it instanceof RLH) {
tmp.sort(__sort_fn__);
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[tmp[i]], tmp[i], i);
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
}
} else {
for (i in it) {
if (it.hasOwnProperty(i)) {
ret2 = __iter__($, $$, it[i], i, j++);
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
}
}
}
} else {
return error(cID, {
"type": 9,
"pos": {
"line": 5,
"col": 12
},
"val": "options"
}, "Invalid loop-iterator reference") || unerr;
}
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 5,
"col": 12
},
"val": "options"
}, "Failed loop iteration", err);
}
return ret;
})();
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
ret += "\n ";
return ret;
}
var i, j = 0,
len, ret = "",
it, tmp;
try {
it = $.settings;
if (it == null) {
return "";
}
if (Object.prototype.toString.call(it) === "[object Array]") {
len = it.length;
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[i], "" + i, i);
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
}
} else if (typeof it === "object") {
tmp = Object.keys(it);
len = tmp.length;
if (it instanceof RLH) {
tmp.sort(__sort_fn__);
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[tmp[i]], tmp[i], i);
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
}
} else {
for (i in it) {
if (it.hasOwnProperty(i)) {
ret2 = __iter__($, $$, it[i], i, j++);
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
}
}
}
} else {
return error(cID, {
"type": 9,
"pos": {
"line": 3,
"col": 8
},
"val": "$.settings"
}, "Invalid loop-iterator reference") || unerr;
}
} catch (err) {
return error(cID, {
"type": 9,
"pos": {
"line": 3,
"col": 8
},
"val": "$.settings"
}, "Failed loop iteration", err);
}
return ret;
})();
if (ret2 instanceof G.TemplateError) {
return ret2;
} else {
ret += ret2;
}
ret += "\n";
return ret;
}, "3.html#settings", {
"type": 2,
"pos": {
"line": 1,
"col": 0
},
"val": "{$: '#settings' }"
});
})(this.grips || grips);
// Here's the same template code from above generation, but without the
// debugging guards.
(function (G) {
function __sort_fn__(a, b) {
return a - b;
}
var partial = G.definePartial,
clone = G.cloneObj,
extend = G.extend,
esc = G.strEscapes,
unerr = new Error("Unknown error"),
RLH = G.RangeLiteralHash,
cID = "3.html";
partial(function ($, $$) {
$ = $ || {};
$$ = clone($$) || {};
var i, ret = "",
ret2, _;
ret += "\n <h1>Settings</h1>\n ";
ret2 = (function () {
function __iter__($, $$, value, key, index) {
var i, ret = "",
ret2, _;
if (value == null) return ret;
$$ = clone($$);
_ = {
value: value,
key: key,
index: index,
even: (index % 2) === 0,
odd: (index % 2) === 1,
first: (index === 0),
last: (index === len - 1)
};
$$.name = _.key;
$$.options = {};
var _set = ['low', 'high'];
for (i = 0; i < 2; i++) {
$$.options[_set[i]] = (_.value === _set[i]) ? "checked" : "";
}
ret += "\n <h2>";
ret += $$.name;
ret += "</h2>\n ";
ret2 = (function () {
function __iter__($, $$, value, key, index) {
var i, ret = "",
ret2, _;
if (value == null) return ret;
$$ = clone($$);
_ = {
value: value,
key: key,
index: index,
even: (index % 2) === 0,
odd: (index % 2) === 1,
first: (index === 0),
last: (index === len - 1)
};
ret += "\n <input type=\"radio\" name=\"";
ret += $$.name;
ret += "\" value=\"";
ret += _.key;
ret += "\" ";
ret += _.value;
ret += "> ";
ret += _.key;
ret += "\n ";
return ret;
}
var i, j = 0,
len, ret = "",
it, tmp;
it = $$.options;
if (it == null) {
return "";
}
if (Object.prototype.toString.call(it) === "[object Array]") {
len = it.length;
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[i], "" + i, i);
ret += ret2;
}
} else if (typeof it === "object") {
tmp = Object.keys(it);
len = tmp.length;
if (it instanceof RLH) {
tmp.sort(__sort_fn__);
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[tmp[i]], tmp[i], i);
ret += ret2;
}
} else {
for (i in it) {
if (it.hasOwnProperty(i)) {
ret2 = __iter__($, $$, it[i], i, j++);
ret += ret2;
}
}
}
} else {
return unerr;
}
return ret;
})();
ret += ret2;
ret += "\n ";
return ret;
}
var i, j = 0,
len, ret = "",
it, tmp;
it = $.settings;
if (it == null) {
return "";
}
if (Object.prototype.toString.call(it) === "[object Array]") {
len = it.length;
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[i], "" + i, i);
ret += ret2;
}
} else if (typeof it === "object") {
tmp = Object.keys(it);
len = tmp.length;
if (it instanceof RLH) {
tmp.sort(__sort_fn__);
for (i = 0; i < len; i++) {
ret2 = __iter__($, $$, it[tmp[i]], tmp[i], i);
ret += ret2;
}
} else {
for (i in it) {
if (it.hasOwnProperty(i)) {
ret2 = __iter__($, $$, it[i], i, j++);
ret += ret2;
}
}
}
} else {
return unerr;
}
return ret;
})();
ret += ret2;
ret += "\n";
return ret;
}, "3.html#settings");
})(this.grips || grips);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment