Expose the context to a lambda fragment.
This allows the lambda to take the context and turn around and render it using a totally different template, if desired.
This commit is contained in:
@@ -40,6 +40,12 @@ public class Template
|
|||||||
* the variable context that was in effect at the time the lambda was called.
|
* the variable context that was in effect at the time the lambda was called.
|
||||||
*/
|
*/
|
||||||
public abstract class Fragment {
|
public abstract class Fragment {
|
||||||
|
/** Returns the context object in effect for this fragment. The actual type of the object
|
||||||
|
* depends on the structure of the data passed to the top-level template. You know where
|
||||||
|
* your lambdas are executed, so you know what type to which to cast the context in order
|
||||||
|
* to inspect it (be that a {@code Map} or a POJO or something else). */
|
||||||
|
public abstract Object context ();
|
||||||
|
|
||||||
/** Executes this fragment; writes its result to {@code out}. */
|
/** Executes this fragment; writes its result to {@code out}. */
|
||||||
public abstract void execute (Writer out);
|
public abstract void execute (Writer out);
|
||||||
|
|
||||||
@@ -107,14 +113,15 @@ public class Template
|
|||||||
|
|
||||||
protected Fragment createFragment (final Segment[] segs, final Context currentCtx) {
|
protected Fragment createFragment (final Segment[] segs, final Context currentCtx) {
|
||||||
return new Fragment() {
|
return new Fragment() {
|
||||||
|
@Override public Object context () {
|
||||||
|
return currentCtx.data;
|
||||||
|
}
|
||||||
@Override public void execute (Writer out) {
|
@Override public void execute (Writer out) {
|
||||||
execute(currentCtx, out);
|
execute(currentCtx, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void execute (Object context, Writer out) {
|
@Override public void execute (Object context, Writer out) {
|
||||||
execute(currentCtx.nest(context, 0, false, false), out);
|
execute(currentCtx.nest(context, 0, false, false), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void execute (Context ctx, Writer out) {
|
private void execute (Context ctx, Writer out) {
|
||||||
for (Segment seg : segs) {
|
for (Segment seg : segs) {
|
||||||
seg.execute(Template.this, ctx, out);
|
seg.execute(Template.this, ctx, out);
|
||||||
|
|||||||
@@ -665,16 +665,41 @@ public class MustacheTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testLambdaWithContext () {
|
@Test public void testLambdaWithContext () {
|
||||||
test("a in l1, a in l2", "{{#l1}}{{a}}{{/l1}}, {{#l2}}{{a}}{{/l2}}",
|
test("a in l1, a in l2", "{{#l1}}{{a}}{{/l1}}, {{#l2}}{{a}}{{/l2}}", context(
|
||||||
context("l1", new Mustache.Lambda() {
|
"l1", new Mustache.Lambda() {
|
||||||
public void execute (Template.Fragment frag, Writer out) throws IOException {
|
public void execute (Template.Fragment frag, Writer out) throws IOException {
|
||||||
frag.execute(context("a", "a in l1"), out);
|
frag.execute(context("a", "a in l1"), out);
|
||||||
}
|
}
|
||||||
}, "l2", new Mustache.Lambda() {
|
},
|
||||||
public void execute (Template.Fragment frag, Writer out) throws IOException {
|
"l2", new Mustache.Lambda() {
|
||||||
frag.execute(context("a", "a in l2"), out);
|
public void execute (Template.Fragment frag, Writer out) throws IOException {
|
||||||
}
|
frag.execute(context("a", "a in l2"), out);
|
||||||
}));
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testContextPokingLambda () {
|
||||||
|
Mustache.Compiler c = Mustache.compiler();
|
||||||
|
|
||||||
|
class Foo { public int foo = 1; }
|
||||||
|
final Template lfoo = c.compile("{{foo}}");
|
||||||
|
assertEquals("1", lfoo.execute(new Foo()));
|
||||||
|
|
||||||
|
class Bar { public String bar = "one"; }
|
||||||
|
final Template lbar = c.compile("{{bar}}");
|
||||||
|
assertEquals("one", lbar.execute(new Bar()));
|
||||||
|
|
||||||
|
test(c, "1oneone1one!", "{{#events}}{{#renderEvent}}{{/renderEvent}}{{/events}}", context(
|
||||||
|
"renderEvent", new Mustache.Lambda() {
|
||||||
|
public void execute (Template.Fragment frag, Writer out) throws IOException {
|
||||||
|
Object ctx = frag.context();
|
||||||
|
if (ctx instanceof Foo) lfoo.execute(ctx, out);
|
||||||
|
else if (ctx instanceof Bar) lbar.execute(ctx, out);
|
||||||
|
else out.write("!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events", Arrays.asList(
|
||||||
|
new Foo(), new Bar(), new Bar(), new Foo(), new Bar(), "wtf?")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testNonStandardDefaultDelims () {
|
@Test public void testNonStandardDefaultDelims () {
|
||||||
|
|||||||
Reference in New Issue
Block a user