Use Java code formatting for examples.
This commit is contained in:
@@ -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: <bar>
|
// not: <bar>
|
||||||
|
```
|
||||||
|
|
||||||
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
|
||||||
=============
|
=============
|
||||||
|
|||||||
Reference in New Issue
Block a user