Add option to treat zero as a falsy value

In javascript implementation, zero is a falsy value and is treated as a false boolean.
An option is added (false by default) to treat zero as a falsy value as in javascript implementation.

It means that section like:

{{#zeroValue}}foo{{/zeroValue}}

will not be rendered.
This commit is contained in:
Mickael Jeanroy
2013-05-08 22:24:40 +02:00
parent 426faf92c5
commit 4300b1213e
2 changed files with 48 additions and 10 deletions
@@ -54,6 +54,10 @@ public class Mustache
* mustache implementation. Default is false. */ * mustache implementation. Default is false. */
public final boolean emptyStringIsFalse; public final boolean emptyStringIsFalse;
/** If this value is true, zero will be treated as a false value, as in JavaScript
* mustache implementation. Default is false. */
public final boolean zeroIsFalse;
/** The template loader in use during this compilation. */ /** The template loader in use during this compilation. */
public final TemplateLoader loader; public final TemplateLoader loader;
@@ -76,7 +80,7 @@ public class Mustache
/** Returns a compiler that either does or does not escape HTML by default. */ /** Returns a compiler that either does or does not escape HTML by default. */
public Compiler escapeHTML (boolean escapeHTML) { public Compiler escapeHTML (boolean escapeHTML) {
return new Compiler(escapeHTML, this.standardsMode, this.nullValue, this.missingIsNull, return new Compiler(escapeHTML, this.standardsMode, this.nullValue, this.missingIsNull,
this.emptyStringIsFalse, this.loader, this.collector, this.delims); this.emptyStringIsFalse, this.zeroIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that either does or does not use standards mode. Standards mode /** Returns a compiler that either does or does not use standards mode. Standards mode
@@ -84,7 +88,7 @@ public class Mustache
* context. */ * context. */
public Compiler standardsMode (boolean standardsMode) { public Compiler standardsMode (boolean standardsMode) {
return new Compiler(this.escapeHTML, standardsMode, this.nullValue, this.missingIsNull, return new Compiler(this.escapeHTML, standardsMode, this.nullValue, this.missingIsNull,
this.emptyStringIsFalse, this.loader, this.collector, this.delims); this.emptyStringIsFalse, this.zeroIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that will use the given value for any variable that is missing, or /** Returns a compiler that will use the given value for any variable that is missing, or
@@ -92,7 +96,7 @@ public class Mustache
* supplied default for missing keys and existing keys that return null values. */ * supplied default for missing keys and existing keys that return null values. */
public Compiler defaultValue (String defaultValue) { public Compiler defaultValue (String defaultValue) {
return new Compiler(this.escapeHTML, this.standardsMode, defaultValue, true, return new Compiler(this.escapeHTML, this.standardsMode, defaultValue, true,
this.emptyStringIsFalse, this.loader, this.collector, this.delims); this.emptyStringIsFalse, this.zeroIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that will use the given value for any variable that resolves to /** Returns a compiler that will use the given value for any variable that resolves to
@@ -108,27 +112,34 @@ public class Mustache
* </ul> */ * </ul> */
public Compiler nullValue (String nullValue) { public Compiler nullValue (String nullValue) {
return new Compiler(this.escapeHTML, this.standardsMode, nullValue, false, return new Compiler(this.escapeHTML, this.standardsMode, nullValue, false,
this.emptyStringIsFalse, this.loader, this.collector, this.delims); this.emptyStringIsFalse, this.zeroIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that will treat empty string as a false value if parameter is true. */ /** Returns a compiler that will treat empty string as a false value if parameter is true. */
public Compiler emptyStringIsFalse (boolean emptyStringIsFalse) { public Compiler emptyStringIsFalse (boolean emptyStringIsFalse) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, emptyStringIsFalse, this.loader, this.collector, this.missingIsNull, emptyStringIsFalse, this.zeroIsFalse, this.loader, this.collector,
this.delims);
}
/** Returns a compiler that will treat zero as a false value if parameter is true. */
public Compiler zeroIsFalse (boolean zeroIsFalse) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, zeroIsFalse, this.loader, this.collector,
this.delims); this.delims);
} }
/** Returns a compiler configured to use the supplied template loader to handle partials. */ /** Returns a compiler configured to use the supplied template loader to handle partials. */
public Compiler withLoader (TemplateLoader loader) { public Compiler withLoader (TemplateLoader loader) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, loader, this.collector, this.missingIsNull, this.emptyStringIsFalse, this.zeroIsFalse, loader, this.collector,
this.delims); this.delims);
} }
/** Returns a compiler configured to use the supplied collector. */ /** Returns a compiler configured to use the supplied collector. */
public Compiler withCollector (Collector collector) { public Compiler withCollector (Collector collector) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, this.loader, collector, this.missingIsNull, this.emptyStringIsFalse, this.zeroIsFalse, this.loader, collector,
this.delims); this.delims);
} }
@@ -137,7 +148,7 @@ public class Mustache
* opening delims and C and D are closing delims. */ * opening delims and C and D are closing delims. */
public Compiler withDelims (String delims) { public Compiler withDelims (String delims) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, this.loader, this.missingIsNull, this.emptyStringIsFalse, this.zeroIsFalse, this.loader,
this.collector, new Delims().updateDelims(delims)); this.collector, new Delims().updateDelims(delims));
} }
@@ -148,13 +159,14 @@ public class Mustache
} }
protected Compiler (boolean escapeHTML, boolean standardsMode, String nullValue, protected Compiler (boolean escapeHTML, boolean standardsMode, String nullValue,
boolean missingIsNull, boolean emptyStringIsFalse, TemplateLoader loader, boolean missingIsNull, boolean emptyStringIsFalse, boolean zeroIsFalse, TemplateLoader loader,
Collector collector, Delims delims) { Collector collector, Delims delims) {
this.escapeHTML = escapeHTML; this.escapeHTML = escapeHTML;
this.standardsMode = standardsMode; this.standardsMode = standardsMode;
this.nullValue = nullValue; this.nullValue = nullValue;
this.missingIsNull = missingIsNull; this.missingIsNull = missingIsNull;
this.emptyStringIsFalse = emptyStringIsFalse; this.emptyStringIsFalse = emptyStringIsFalse;
this.zeroIsFalse = zeroIsFalse;
this.loader = loader; this.loader = loader;
this.collector = collector; this.collector = collector;
this.delims = delims; this.delims = delims;
@@ -210,7 +222,7 @@ public class Mustache
* Returns a compiler that escapes HTML by default and does not use standards mode. * Returns a compiler that escapes HTML by default and does not use standards mode.
*/ */
public static Compiler compiler () { public static Compiler compiler () {
return new Compiler(true, false, null, true, false, FAILING_LOADER, new DefaultCollector(), return new Compiler(true, false, null, true, false, false, FAILING_LOADER, new DefaultCollector(),
new Delims()); new Delims());
} }
@@ -698,6 +710,8 @@ public class Mustache
} }
} else if (_compiler.emptyStringIsFalse && "".equals(value)) { } else if (_compiler.emptyStringIsFalse && "".equals(value)) {
// omit the section // omit the section
} else if (value != null && value instanceof Number && ((Number) value).longValue() == 0) {
// omit the section
} else { } else {
executeSegs(tmpl, ctx.nest(value, 0, false, false), out); executeSegs(tmpl, ctx.nest(value, 0, false, false), out);
} }
@@ -145,6 +145,30 @@ public class MustacheTest
}); });
} }
@Test public void testSectionWithLongValueZero () {
test(Mustache.compiler().zeroIsFalse(true), "", "{{#foo}}test{{/foo}}", new Object() {
Long foo = 0L;
});
}
@Test public void testSectionWithIntegerValueZero () {
test(Mustache.compiler().zeroIsFalse(true), "", "{{#foo}}test{{/foo}}", new Object() {
Integer foo = 0;
});
}
@Test public void testSectionWithFloatValueZero () {
test(Mustache.compiler().zeroIsFalse(true), "", "{{#foo}}test{{/foo}}", new Object() {
Float foo = 0F;
});
}
@Test public void testSectionWithDoubleValueZero () {
test(Mustache.compiler().zeroIsFalse(true), "", "{{#foo}}test{{/foo}}", new Object() {
Double foo = 0D;
});
}
@Test public void testMissingSection () { @Test public void testMissingSection () {
test("", "{{#foo}}{{bar}}{{/foo}}", new Object() { test("", "{{#foo}}{{bar}}{{/foo}}", new Object() {
// no foo // no foo