Skip to content

Instantly share code, notes, and snippets.

@spullara
Created April 7, 2013 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spullara/5331831 to your computer and use it in GitHub Desktop.
Save spullara/5331831 to your computer and use it in GitHub Desktop.
Mustache.js supports array indexes but it isn't in the spec and isn't likely to be added. If you need support, you can extend mustache.java to support it using something like this.
package com.github.mustachejava;
import com.github.mustachejava.reflect.ReflectionObjectHandler;
import org.junit.Test;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Set;
import static org.junit.Assert.assertEquals;
/**
* Shows a simple way to add indexes for arrays.
* <p/>
* User: sam
* Date: 4/7/13
* Time: 11:12 AM
*/
public class ArraysIndexesTest {
@Test
public void testArrayIndexExtension() throws IOException {
String template = "<ol>\n" +
" <li>{{test.1}}</li>\n" +
" <li>{{test.0}}</li>\n" +
" <li>{{test.3}}</li>\n" +
"</ol>\n" +
"<ol>\n" +
"{{#test}}\n" +
" <li>{{.}}</li>\n" +
"{{/test}}\n" +
"</ol>";
String result = "<ol>\n" +
" <li>1</li>\n" +
" <li>0</li>\n" +
" <li>3</li>\n" +
"</ol>\n" +
"<ol>\n" +
" <li>0</li>\n" +
" <li>1</li>\n" +
" <li>2</li>\n" +
" <li>3</li>\n" +
"</ol>";
Object scope = new Object() {
int[] test = { 0, 1, 2, 3 };
};
ReflectionObjectHandler oh = new ReflectionObjectHandler() {
@Override
public Object coerce(final Object object) {
if (object != null && object.getClass().isArray()) {
return new ArrayMap(object);
}
return super.coerce(object);
}
};
DefaultMustacheFactory mf = new DefaultMustacheFactory();
mf.setObjectHandler(oh);
Mustache m = mf.compile(new StringReader(template), "template");
StringWriter writer = new StringWriter();
m.execute(writer, scope).flush();
assertEquals(result, writer.toString());
}
private static class ArrayMap extends AbstractMap<Object, Object> implements Iterable<Object> {
private final Object object;
public ArrayMap(Object object) {
this.object = object;
}
@Override
public Object get(Object key) {
try {
int index = Integer.parseInt(key.toString());
return Array.get(object, index);
} catch (NumberFormatException nfe) {
return null;
}
}
@Override
public boolean containsKey(Object key) {
return get(key) != null;
}
@Override
public Set<Entry<Object, Object>> entrySet() {
throw new UnsupportedOperationException();
}
/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
@Override
public Iterator<Object> iterator() {
return new Iterator<Object>() {
int index = 0;
int length = Array.getLength(object);
@Override
public boolean hasNext() {
return index < length;
}
@Override
public Object next() {
return Array.get(object, index++);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment