Skip to content

Commit

Permalink
add strict option instead of existence sections
Browse files Browse the repository at this point in the history
  • Loading branch information
amccollum committed Oct 4, 2011
1 parent fb7a2d8 commit ab5fe9a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 61 deletions.
14 changes: 0 additions & 14 deletions README.md
Expand Up @@ -102,20 +102,6 @@ only be rendered if the value is false or the given array is empty:
{/foo}


#### Existence Sections ####

Existence sections are rendered when the value is present.

{?foo}
The foo value was defined, but may be false.
{/foo}

For brevity, existence sections can be combined with normal or inverted sections:

{?:foo}
This section acts like a normal section, but will be omitted if foo is undefined.
{/foo}

Acknowledgements
----------------

Expand Down
27 changes: 14 additions & 13 deletions lib/wings.js
@@ -1,5 +1,6 @@
!(function(wings) {
var escapeXML, isArray, parse_re, renderRawTemplate, replaceBraces, restoreBraces, _ref;
wings.strict = false;
wings.renderTemplate = function(template, data, links) {
template = replaceBraces(template);
template = renderRawTemplate(template, data, links);
Expand Down Expand Up @@ -31,26 +32,18 @@
}
});
};
parse_re = /\s*\{([?:!]+)\s*([^}]*?)\s*\}([\S\s]+?)\s*\{\/\s*\2\s*\}|\{(\#)\s*[\S\s]+?\s*\#\}|\{([@&]?)\s*([^}]*?)\s*\}/mg;
parse_re = /\s*\{([:!])\s*([^}]*?)\s*\}([\S\s]+?)\s*\{\/\s*\2\s*\}|\{(\#)\s*[\S\s]+?\s*\#\}|\{([@&]?)\s*([^}]*?)\s*\}/mg;
return renderRawTemplate = function(template, data, links) {
return template.replace(parse_re, function(all, section_op, section_name, section_content, comment_op, tag_op, tag_name) {
var content, i, link, name, op, part, parts, rest, v, value, _len, _ref2;
op = section_op || comment_op || tag_op;
name = section_name || tag_name;
content = section_content;
switch (op) {
case '?':
if (name in data) {
return renderRawTemplate(content, data, links);
} else {
return "";
}
break;
case ':':
case '?:':
value = data[name];
if (!(value != null)) {
if (op === ':') {
if (wings.strict) {
throw "Invalid section: " + (JSON.stringify(data)) + ": " + name;
} else {
return "";
Expand All @@ -77,7 +70,7 @@
case '?!':
value = data[name];
if (!(value != null)) {
if (op === '!') {
if (wings.strict) {
throw "Invalid inverted section: " + (JSON.stringify(data)) + ": " + name;
} else {
return "";
Expand All @@ -93,7 +86,11 @@
case '@':
link = links ? links[name] : null;
if (!(link != null)) {
throw "Invalid link: " + (JSON.stringify(links)) + ": " + name;
if (wings.strict) {
throw "Invalid link: " + (JSON.stringify(links)) + ": " + name;
} else {
return "";
}
} else if (typeof link === 'function') {
link = link.call(data);
}
Expand All @@ -107,7 +104,11 @@
value = value[part];
}
if (!(value != null)) {
throw "Invalid value: " + (JSON.stringify(data)) + ": " + name;
if (wings.strict) {
throw "Invalid value: " + (JSON.stringify(data)) + ": " + name;
} else {
return "";
}
} else if (typeof value === 'function') {
value = value.call(data);
}
Expand Down
27 changes: 7 additions & 20 deletions src/test/wings-test.coffee
Expand Up @@ -178,29 +178,16 @@ vows.add 'templates'
tmpl3: 'nested {{ {:truthy} {{ braces }} {{ {/truthy} }}',
'''.replace(/\n/g, '')

'templates with existence sections':
'templates with undefined sections':
topic: [
t('{?absent}foo{/absent}bar', {}),
t('{?exists}foo{/exists}bar', {exists: true}),
t('{?falsy}foo{/falsy}bar', {falsy: false}),
t('{:absent}foo{/absent}bar', {}),
t('{!absent}foo{/absent}bar', {}),
t('{:exists}foo{/exists}bar', {exists: true}),
t('{!falsy}foo{/falsy}bar', {falsy: false}),
]

'should only include the section when the tag is defined': (topics) ->
'should only include the section when the value is defined': (topics) ->
equal topics[0], 'bar'
equal topics[1], 'foobar'
equal topics[1], 'bar'
equal topics[2], 'foobar'

'templates with combined sections':
topic: [
t('{?:absent}{foo}{bar}{baz}{/absent}', {}),
t('{?:obj}{foo}{bar}{baz}{/obj}', {obj: {foo: '1', bar: '2', baz: '3'}}),
t('{?!absent}foo{/absent}bar', {}),
t('{?!falsy}foo{/falsy}bar', {falsy: false}),
]

'should use the object as the new environment': (topics) ->
equal topics[0], ''
equal topics[1], '123'
equal topics[2], 'bar'
equal topics[3], 'foobar'

28 changes: 14 additions & 14 deletions src/wings/wings.coffee
@@ -1,12 +1,13 @@
!((wings) ->
wings.strict = false

wings.renderTemplate = (template, data, links) ->
# Replace escaped braces with an obscure unicode curly brace
template = replaceBraces(template)
template = renderRawTemplate(template, data, links)
template = restoreBraces(template)
return template


replaceBraces = (template) -> template.replace(/\{\{/g, '\ufe5b').replace(/\}\}/g, '\ufe5d')
restoreBraces = (template) -> template.replace(/\ufe5b/g, '{').replace(/\ufe5d/g, '}')

Expand All @@ -22,7 +23,7 @@
else return s

parse_re = ///
\s* \{([?:!]+) \s* ([^}]*?) \s* \} ([\S\s]+?) \s* \{/ \s* \2 \s*\} | # sections
\s* \{([:!]) \s* ([^}]*?) \s* \} ([\S\s]+?) \s* \{/ \s* \2 \s*\} | # sections
\{(\#) \s* [\S\s]+? \s* \#\} | # comments
\{([@&]?) \s* ([^}]*?) \s* \} # tags
///mg
Expand All @@ -34,17 +35,10 @@
content = section_content

switch op
when '?' # existence section
if name of data
return renderRawTemplate(content, data, links)

else
return ""

when ':', '?:' # section
when ':' # section
value = data[name]
if not value?
if op == ':'
if wings.strict
throw "Invalid section: #{JSON.stringify(data)}: #{name}"
else
return ""
Expand Down Expand Up @@ -72,7 +66,7 @@
when '!', '?!' # inverted section
value = data[name]
if not value?
if op == '!'
if wings.strict
throw "Invalid inverted section: #{JSON.stringify(data)}: #{name}"
else
return ""
Expand All @@ -90,7 +84,10 @@
link = if links then links[name] else null

if not link?
throw "Invalid link: #{JSON.stringify(links)}: #{name}"
if wings.strict
throw "Invalid link: #{JSON.stringify(links)}: #{name}"
else
return ""

else if typeof link == 'function'
link = link.call(data)
Expand All @@ -105,7 +102,10 @@
value = value[part]

if not value?
throw "Invalid value: #{JSON.stringify(data)}: #{name}"
if wings.strict
throw "Invalid value: #{JSON.stringify(data)}: #{name}"
else
return ""

else if typeof value == 'function'
value = value.call(data)
Expand Down

0 comments on commit ab5fe9a

Please sign in to comment.