diff --git a/src/main/java/com/samskivert/mustache/Mustache.java b/src/main/java/com/samskivert/mustache/Mustache.java index 37599f7..9cbd90c 100644 --- a/src/main/java/com/samskivert/mustache/Mustache.java +++ b/src/main/java/com/samskivert/mustache/Mustache.java @@ -387,12 +387,16 @@ public class Mustache return; // TODO: configurable behavior on missing values } if (value instanceof Iterable) { + value = ((Iterable)value).iterator(); + } + if (value instanceof Iterator) { Template.Mode mode = null; - for (Iterator iter = ((Iterable)value).iterator(); iter.hasNext(); ) { + int index = 0; + for (Iterator iter = (Iterator)value; iter.hasNext(); ) { Object elem = iter.next(); mode = (mode == null) ? Template.Mode.FIRST : (iter.hasNext() ? Template.Mode.OTHER : Template.Mode.LAST); - executeSegs(tmpl, ctx.nest(elem, mode), out); + executeSegs(tmpl, ctx.nest(elem, ++index, mode), out); } } else if (value instanceof Boolean) { if ((Boolean)value) { @@ -402,18 +406,10 @@ public class Mustache for (int ii = 0, ll = Array.getLength(value); ii < ll; ii++) { Template.Mode mode = (ii == 0) ? Template.Mode.FIRST : ((ii == ll-1) ? Template.Mode.LAST : Template.Mode.OTHER); - executeSegs(tmpl, ctx.nest(Array.get(value, ii), mode), out); - } - } else if (value instanceof Iterator) { - Template.Mode mode = null; - for (Iterator iter = (Iterator)value; iter.hasNext(); ) { - Object elem = iter.next(); - mode = (mode == null) ? Template.Mode.FIRST : - (iter.hasNext() ? Template.Mode.OTHER : Template.Mode.LAST); - executeSegs(tmpl, ctx.nest(elem, mode), out); + executeSegs(tmpl, ctx.nest(Array.get(value, ii), ii+1, mode), out); } } else { - executeSegs(tmpl, ctx.nest(value, Template.Mode.OTHER), out); + executeSegs(tmpl, ctx.nest(value, 0, Template.Mode.OTHER), out); } } } diff --git a/src/main/java/com/samskivert/mustache/Template.java b/src/main/java/com/samskivert/mustache/Template.java index dcc4e93..7a4d198 100644 --- a/src/main/java/com/samskivert/mustache/Template.java +++ b/src/main/java/com/samskivert/mustache/Template.java @@ -42,7 +42,7 @@ public class Template */ public void execute (Object context, Writer out) throws MustacheException { - Context ctx = new Context(context, null, Mode.OTHER); + Context ctx = new Context(context, null, 0, Mode.OTHER); for (Segment seg : _segs) { seg.execute(this, ctx, out); } @@ -100,6 +100,8 @@ public class Template return ctx.mode == Mode.FIRST; } else if (name == LAST_NAME) { return ctx.mode == Mode.LAST; + } else if (name == INDEX_NAME) { + return ctx.index; } while (ctx != null) { @@ -242,16 +244,18 @@ public class Template { public final Object data; public final Context parent; + public final int index; public final Mode mode; - public Context (Object data, Context parent, Mode mode) { + public Context (Object data, Context parent, int index, Mode mode) { this.data = data; this.parent = parent; + this.index = index; this.mode = mode; } - public Context nest (Object data, Mode mode) { - return new Context(data, this, mode); + public Context nest (Object data, int index, Mode mode) { + return new Context(data, this, index, mode); } } @@ -309,4 +313,5 @@ public class Template protected static final String THIS_NAME = "this".intern(); protected static final String FIRST_NAME = "-first".intern(); protected static final String LAST_NAME = "-last".intern(); + protected static final String INDEX_NAME = "-index".intern(); } diff --git a/src/test/java/com/samskivert/mustache/MustacheTest.java b/src/test/java/com/samskivert/mustache/MustacheTest.java index 30a41b8..ab3be55 100644 --- a/src/test/java/com/samskivert/mustache/MustacheTest.java +++ b/src/test/java/com/samskivert/mustache/MustacheTest.java @@ -188,6 +188,11 @@ public class MustacheTest context("things", Arrays.asList("foo", "bar", "baz"))); } + @Test public void testIndex () { + test("123", "{{#things}}{{-index}}{{/things}}", + context("things", Arrays.asList("foo", "bar", "baz"))); + } + protected void test (String expected, String template, Object ctx) { assertEquals(expected, Mustache.compiler().compile(template).execute(ctx));