Use Java code formatting for examples.

This commit is contained in:
Michael Bayne
2015-03-16 20:30:42 -07:00
parent 1c50c28122
commit 4091bf1091
+42
View File
@@ -45,18 +45,22 @@ Usage
Using JMustache is very simple. Supply your template as a `String` or a `Reader` and get back a Using JMustache is very simple. Supply your template as a `String` or a `Reader` and get back a
`Template` that you can execute on any context: `Template` that you can execute on any context:
```java
String text = "One, two, {{three}}. Three sir!"; String text = "One, two, {{three}}. Three sir!";
Template tmpl = Mustache.compiler().compile(text); Template tmpl = Mustache.compiler().compile(text);
Map<String, String> data = new HashMap<String, String>(); Map<String, String> data = new HashMap<String, String>();
data.put("three", "five"); data.put("three", "five");
System.out.println(tmpl.execute(data)); System.out.println(tmpl.execute(data));
// result: "One, two, five. Three sir!" // result: "One, two, five. Three sir!"
```
Use `Reader` and `Writer` if you're doing something more serious: Use `Reader` and `Writer` if you're doing something more serious:
```java
void executeTemplate (Reader template, Writer out, Map<String, String> data) { void executeTemplate (Reader template, Writer out, Map<String, String> data) {
Mustache.compiler().compile(template).execute(data, out); Mustache.compiler().compile(template).execute(data, out);
} }
```
The execution context can be any Java object. Variables will be resolved via the following The execution context can be any Java object. Variables will be resolved via the following
mechanisms: mechanisms:
@@ -68,6 +72,7 @@ mechanisms:
Example: Example:
```java
class Person { class Person {
public final String name; public final String name;
public Person (String name, int age) { public Person (String name, int age) {
@@ -88,6 +93,7 @@ Example:
// result: // result:
// Elvis: 75 // Elvis: 75
// Madonna: 52 // Madonna: 52
```
As you can see from the example, the fields (and methods) need not be public. The `persons` field As you can see from the example, the fields (and methods) need not be public. The `persons` field
in the anonymous class created to act as a context is accessible. Note that the use of non-public in the anonymous class created to act as a context is accessible. Note that the use of non-public
@@ -115,6 +121,7 @@ Partials
If you wish to make use of partials (e.g. `{{>subtmpl}}`) you must provide a If you wish to make use of partials (e.g. `{{>subtmpl}}`) you must provide a
`Mustache.TemplateLoader` to the compiler when creating it. For example: `Mustache.TemplateLoader` to the compiler when creating it. For example:
```java
final File templateDir = ...; final File templateDir = ...;
Mustache.Compiler c = Mustache.compiler().withLoader(new Mustache.TemplateLoader() { Mustache.Compiler c = Mustache.compiler().withLoader(new Mustache.TemplateLoader() {
public Reader getTemplate (String name) { public Reader getTemplate (String name) {
@@ -123,6 +130,7 @@ If you wish to make use of partials (e.g. `{{>subtmpl}}`) you must provide a
}); });
String tmpl = "...{{>subtmpl}}..."; String tmpl = "...{{>subtmpl}}...";
c.compile(tmpl).execute(); c.compile(tmpl).execute();
```
The above snippet will load `new File(templateDir, "subtmpl")` when compiling the template. The above snippet will load `new File(templateDir, "subtmpl")` when compiling the template.
@@ -133,6 +141,7 @@ JMustache implements lambdas by passing you a `Template.Fragment` instance which
execute the fragment of the template that was passed to the lambda. You can decorate the results of execute the fragment of the template that was passed to the lambda. You can decorate the results of
the fragment execution, as shown in the standard Mustache documentation on lambdas: the fragment execution, as shown in the standard Mustache documentation on lambdas:
```java
String tmpl = "{{#bold}}{{name}} is awesome.{{/bold}}"; String tmpl = "{{#bold}}{{name}} is awesome.{{/bold}}";
Mustache.compiler().compile(tmpl).execute(new Object() { Mustache.compiler().compile(tmpl).execute(new Object() {
String name = "Willy"; String name = "Willy";
@@ -146,10 +155,12 @@ the fragment execution, as shown in the standard Mustache documentation on lambd
}); });
// result: // result:
<b>Willy is awesome.</b> <b>Willy is awesome.</b>
```
You can also obtain the results of the fragment execution to do things like internationalization or You can also obtain the results of the fragment execution to do things like internationalization or
caching: caching:
```java
Object ctx = new Object() { Object ctx = new Object() {
Mustache.Lambda i18n = new Mustache.Lambda() { Mustache.Lambda i18n = new Mustache.Lambda() {
public void execute (Template.Fragment frag, Writer out) throws IOException { public void execute (Template.Fragment frag, Writer out) throws IOException {
@@ -162,6 +173,7 @@ caching:
// template might look something like: // template might look something like:
<h2>{{#i18n}}title{{/i18n}</h2> <h2>{{#i18n}}title{{/i18n}</h2>
{{#i18n}}welcome_msg{{/i18n}} {{#i18n}}welcome_msg{{/i18n}}
```
Currently there is no support for "unexecuting" the template and obtaining the original Mustache Currently there is no support for "unexecuting" the template and obtaining the original Mustache
template text contained in the section. File a feature request with a sane use case if you have template text contained in the section. File a feature request with a sane use case if you have
@@ -174,6 +186,7 @@ By default, an exception will be thrown any time a variable cannot be resolved,
(except for sections, see below). You can change this behavior in two ways. If you want to provide a (except for sections, see below). You can change this behavior in two ways. If you want to provide a
value for use in all such circumstances, use `defaultValue()`: value for use in all such circumstances, use `defaultValue()`:
```java
String tmpl = "{{exists}} {{nullValued}} {{doesNotExist}}?"; String tmpl = "{{exists}} {{nullValued}} {{doesNotExist}}?";
Mustache.compiler().defaultValue("what").compile(tmpl).execute(new Object() { Mustache.compiler().defaultValue("what").compile(tmpl).execute(new Object() {
String exists = "Say"; String exists = "Say";
@@ -182,10 +195,12 @@ value for use in all such circumstances, use `defaultValue()`:
}); });
// result: // result:
Say what what? Say what what?
```
If you only wish to provide a default value for variables that resolve to null, and wish to If you only wish to provide a default value for variables that resolve to null, and wish to
preserve exceptions in cases where variables cannot be resolved, use `nullValue()`: preserve exceptions in cases where variables cannot be resolved, use `nullValue()`:
```java
String tmpl = "{{exists}} {{nullValued}} {{doesNotExist}}?"; String tmpl = "{{exists}} {{nullValued}} {{doesNotExist}}?";
Mustache.compiler().nullValue("what").compile(tmpl).execute(new Object() { Mustache.compiler().nullValue("what").compile(tmpl).execute(new Object() {
String exists = "Say"; String exists = "Say";
@@ -193,11 +208,13 @@ preserve exceptions in cases where variables cannot be resolved, use `nullValue(
// String doesNotExist // String doesNotExist
}); });
// throws MustacheException when executing the template because doesNotExist cannot be resolved // throws MustacheException when executing the template because doesNotExist cannot be resolved
```
When using a `Map` as a context, `nullValue()` will only be used when the map contains a mapping to When using a `Map` as a context, `nullValue()` will only be used when the map contains a mapping to
`null`. If the map lacks a mapping for a given variable, then it is considered unresolvable and `null`. If the map lacks a mapping for a given variable, then it is considered unresolvable and
throws an exception. throws an exception.
```java
Map<String,String> map = new HashMap<String,String>(); Map<String,String> map = new HashMap<String,String>();
map.put("exists", "Say"); map.put("exists", "Say");
map.put("nullValued", null); map.put("nullValued", null);
@@ -205,6 +222,7 @@ throws an exception.
String tmpl = "{{exists}} {{nullValued}} {{doesNotExist}}?"; String tmpl = "{{exists}} {{nullValued}} {{doesNotExist}}?";
Mustache.compiler().nullValue("what").compile(tmpl).execute(map); Mustache.compiler().nullValue("what").compile(tmpl).execute(map);
// throws MustacheException when executing the template because doesNotExist cannot be resolved // throws MustacheException when executing the template because doesNotExist cannot be resolved
```
### Sections ### Sections
@@ -228,11 +246,13 @@ Not escaping HTML by default
You can change the default HTML escaping behavior when obtaining a compiler: You can change the default HTML escaping behavior when obtaining a compiler:
```java
Mustache.compiler().escapeHTML(false).compile("{{foo}}").execute(new Object() { Mustache.compiler().escapeHTML(false).compile("{{foo}}").execute(new Object() {
String foo = "<bar>"; String foo = "<bar>";
}); });
// result: <bar> // result: <bar>
// not: &lt;bar&gt; // not: &lt;bar&gt;
```
User-defined object formatting User-defined object formatting
------------------------------ ------------------------------
@@ -240,6 +260,7 @@ User-defined object formatting
By default, JMustache uses `String.valueOf` to convert objects to strings when rendering a By default, JMustache uses `String.valueOf` to convert objects to strings when rendering a
template. You can customize this formatting by implementing the `Mustache.Formatter` interface: template. You can customize this formatting by implementing the `Mustache.Formatter` interface:
```java
Mustache.compiler().withFormatter(new Mustache.Formatter() { Mustache.compiler().withFormatter(new Mustache.Formatter() {
public String format (Object value) { public String format (Object value) {
if (value instanceof Date) return _fmt.format((Date)value); if (value instanceof Date) return _fmt.format((Date)value);
@@ -251,6 +272,7 @@ template. You can customize this formatting by implementing the `Mustache.Format
Date today = new Date(); Date today = new Date();
}) })
// result: Date: 2013/01/08 // result: Date: 2013/01/08
```
User-defined escaping rules User-defined escaping rules
--------------------------- ---------------------------
@@ -260,12 +282,14 @@ HTML and plain text.
If you only need to replace fixed strings in the text, you can use `Escapers.simple`: If you only need to replace fixed strings in the text, you can use `Escapers.simple`:
```java
String[][] escapes = {{ "[", "[[" }, { "]", "]]" }}; String[][] escapes = {{ "[", "[[" }, { "]", "]]" }};
Mustache.compiler().withEscaper(Escapers.simple(escapes)). Mustache.compiler().withEscaper(Escapers.simple(escapes)).
compile("{{foo}}").execute(new Object() { compile("{{foo}}").execute(new Object() {
String foo = "[bar]"; String foo = "[bar]";
}); });
// result: [[bar]] // result: [[bar]]
```
Or you can implement the `Mustache.Escaper` interface directly for more control over the escaping Or you can implement the `Mustache.Escaper` interface directly for more control over the escaping
process. process.
@@ -277,19 +301,23 @@ Special variables
You can use the special variable `this` to refer to the context object itself instead of one of its You can use the special variable `this` to refer to the context object itself instead of one of its
members. This is particularly useful when iterating over lists. members. This is particularly useful when iterating over lists.
```java
Mustache.compiler().compile("{{this}}").execute("hello"); // returns: hello Mustache.compiler().compile("{{this}}").execute("hello"); // returns: hello
Mustache.compiler().compile("{{#names}}{{this}}{/names}}").execute(new Object() { Mustache.compiler().compile("{{#names}}{{this}}{/names}}").execute(new Object() {
List<String> names () { return Arrays.asList("Tom", "Dick", "Harry"); } List<String> names () { return Arrays.asList("Tom", "Dick", "Harry"); }
}); });
// result: TomDickHarry // result: TomDickHarry
```
Note that you can also use the special variable `.` to mean the same thing. Note that you can also use the special variable `.` to mean the same thing.
```java
Mustache.compiler().compile("{{.}}").execute("hello"); // returns: hello Mustache.compiler().compile("{{.}}").execute("hello"); // returns: hello
Mustache.compiler().compile("{{#names}}{{.}}{/names}}").execute(new Object() { Mustache.compiler().compile("{{#names}}{{.}}{/names}}").execute(new Object() {
List<String> names () { return Arrays.asList("Tom", "Dick", "Harry"); } List<String> names () { return Arrays.asList("Tom", "Dick", "Harry"); }
}); });
// result: TomDickHarry // result: TomDickHarry
```
`.` is apparently supported by other Mustache implementations, though it does not appear in the `.` is apparently supported by other Mustache implementations, though it does not appear in the
official documentation. official documentation.
@@ -303,11 +331,13 @@ times.
One will often make use of these special variables in an inverted section, as follows: One will often make use of these special variables in an inverted section, as follows:
```java
String tmpl = "{{#things}}{{^-first}}, {{/-first}}{{this}}{{/things}}"; String tmpl = "{{#things}}{{^-first}}, {{/-first}}{{this}}{{/things}}";
Mustache.compiler().compile(tmpl).execute(new Object() { Mustache.compiler().compile(tmpl).execute(new Object() {
List<String> things = Arrays.asList("one", "two", "three"); List<String> things = Arrays.asList("one", "two", "three");
}); });
// result: one, two, three // result: one, two, three
```
Note that the values of `-first` and `-last` refer only to the inner-most enclosing section. If you Note that the values of `-first` and `-last` refer only to the inner-most enclosing section. If you
are processing a section within a section, there is no way to find out whether you are in the first are processing a section within a section, there is no way to find out whether you are in the first
@@ -318,6 +348,7 @@ The `-index` special variable contains 1 for the first iteration through a secti
second, 3 for the third and so forth. It contains 0 at all other times. Note that it also contains second, 3 for the third and so forth. It contains 0 at all other times. Note that it also contains
0 for a section that is populated by a singleton value rather than a list. 0 for a section that is populated by a singleton value rather than a list.
```java
String tmpl = "My favorite things:\n{{#things}}{{-index}}. {{this}}\n{{/things}}"; String tmpl = "My favorite things:\n{{#things}}{{-index}}. {{this}}\n{{/things}}";
Mustache.compiler().compile(tmpl).execute(new Object() { Mustache.compiler().compile(tmpl).execute(new Object() {
List<String> things = Arrays.asList("Peanut butter", "Pen spinning", "Handstands"); List<String> things = Arrays.asList("Peanut butter", "Pen spinning", "Handstands");
@@ -327,6 +358,7 @@ second, 3 for the third and so forth. It contains 0 at all other times. Note tha
// 1. Peanut butter // 1. Peanut butter
// 2. Pen spinning // 2. Pen spinning
// 3. Handstands // 3. Handstands
```
Compound variables Compound variables
------------------ ------------------
@@ -334,17 +366,21 @@ Compound variables
In addition to resolving simple variables using the context, you can use compound variables to In addition to resolving simple variables using the context, you can use compound variables to
extract data from sub-objects of the current context. For example: extract data from sub-objects of the current context. For example:
```java
Mustache.compiler().compile("Hello {{field.who}}!").execute(new Object() { Mustache.compiler().compile("Hello {{field.who}}!").execute(new Object() {
public Object field = new Object() { public Object field = new Object() {
public String who () { return "world"; } public String who () { return "world"; }
} }
}); });
// result: Hello world! // result: Hello world!
```
By taking advantage of reflection and bean-property-style lookups, you can do kooky things: By taking advantage of reflection and bean-property-style lookups, you can do kooky things:
```java
Mustache.compiler().compile("Hello {{class.name}}!").execute(new Object()); Mustache.compiler().compile("Hello {{class.name}}!").execute(new Object());
// result: Hello java.lang.Object! // result: Hello java.lang.Object!
```
Note that compound variables are essentially short-hand for using singleton sections. The above Note that compound variables are essentially short-hand for using singleton sections. The above
examples could also be represented as: examples could also be represented as:
@@ -396,6 +432,7 @@ Nested Contexts
If a variable is not found in a nested context, it is resolved in the next outer context. This If a variable is not found in a nested context, it is resolved in the next outer context. This
allows usage like the following: allows usage like the following:
```java
String template = "{{outer}}:\n{{#inner}}{{outer}}.{{this}}\n{{/inner}}"; String template = "{{outer}}:\n{{#inner}}{{outer}}.{{this}}\n{{/inner}}";
Mustache.compiler().compile(template).execute(new Object() { Mustache.compiler().compile(template).execute(new Object() {
String outer = "foo"; String outer = "foo";
@@ -406,6 +443,7 @@ allows usage like the following:
// foo.bar // foo.bar
// foo.baz // foo.baz
// foo.bif // foo.bif
```
Note that if a variable _is_ defined in an inner context, it shadows the same name in the outer Note that if a variable _is_ defined in an inner context, it shadows the same name in the outer
context. There is presently no way to access the variable from the outer context. context. There is presently no way to access the variable from the outer context.
@@ -417,6 +455,7 @@ For some applications, it may be useful for lambdas to be executed for an invers
than having the section omitted altogether. This allows for proper conditional substitution when than having the section omitted altogether. This allows for proper conditional substitution when
statically translating templates into other languages or contexts: statically translating templates into other languages or contexts:
```java
String template = "{{#condition}}result if true{{/condition}}\n" + String template = "{{#condition}}result if true{{/condition}}\n" +
"{{^condition}}result if false{{/condition}}"; "{{^condition}}result if false{{/condition}}";
Mustache.compiler().compile(template).execute(new Object() { Mustache.compiler().compile(template).execute(new Object() {
@@ -442,6 +481,7 @@ statically translating templates into other languages or contexts:
// results: // results:
// if (condition) {console.log("result if true")} // if (condition) {console.log("result if true")}
// if (!condition) {console.log("result if false")} // if (!condition) {console.log("result if false")}
```
Of course, you are not limited strictly to conditional substitution -- you can use an Of course, you are not limited strictly to conditional substitution -- you can use an
InvertibleLambda whenever you need a single function with two modes of operation. InvertibleLambda whenever you need a single function with two modes of operation.
@@ -452,10 +492,12 @@ Standards Mode
The more intrusive of these extensions, specifically the searching of parent contexts and the use The more intrusive of these extensions, specifically the searching of parent contexts and the use
of compound varables, can be disabled when creating a compiler, like so: of compound varables, can be disabled when creating a compiler, like so:
```java
Map<String,String> ctx = new HashMap<String,String>(); Map<String,String> ctx = new HashMap<String,String>();
ctx.put("foo.bar", "baz"); ctx.put("foo.bar", "baz");
Mustache.compiler().standardsMode(true).compile("{{foo.bar}}").execute(ctx); Mustache.compiler().standardsMode(true).compile("{{foo.bar}}").execute(ctx);
// result: baz // result: baz
```
Thread Safety Thread Safety
============= =============