Skip to content

Commit 702606f

Browse files
committed
add support for dynamicnames
1 parent 9442141 commit 702606f

File tree

7 files changed

+69
-2
lines changed

7 files changed

+69
-2
lines changed

compiler/src/main/java/com/github/mustachejava/DefaultMustacheVisitor.java

+6
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ public void partial(TemplateContext tc, final String variable, String indent) {
7070
list.add(new PartialCode(partialTC, df, variable));
7171
}
7272

73+
@Override
74+
public void dynamicPartial(TemplateContext tc, final String variable, String indent) {
75+
TemplateContext partialTC = new TemplateContext("{{", "}}", tc.file(), tc.line(), tc.startOfLine());
76+
list.add(new DynamicPartialCode(partialTC, df, variable));
77+
}
78+
7379
@Override
7480
public void value(TemplateContext tc, final String variable, boolean encoded) {
7581
list.add(new ValueCode(tc, df, variable, encoded));

compiler/src/main/java/com/github/mustachejava/MustacheParser.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,12 @@ protected Mustache compile(final Reader reader, String tag, final AtomicInteger
199199
String indent = (onlywhitespace && startOfLine) ? out.toString() : "";
200200
out = write(mv, out, file, currentLine.intValue(), startOfLine);
201201
startOfLine = startOfLine & onlywhitespace;
202-
mv.partial(new TemplateContext(sm, em, file, currentLine.get(), startOfLine), variable, indent);
203202

203+
if (variable.trim().startsWith("*")) {
204+
mv.dynamicPartial(new TemplateContext(sm, em, file, currentLine.get(), startOfLine), variable.replaceAll(" ", ""), indent);
205+
} else {
206+
mv.partial(new TemplateContext(sm, em, file, currentLine.get(), startOfLine), variable, indent);
207+
}
204208
// a new line following a partial is dropped
205209
if (specConformWhitespace && startOfLine) {
206210
br.mark(2);

compiler/src/main/java/com/github/mustachejava/MustacheVisitor.java

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public interface MustacheVisitor {
1414

1515
void partial(TemplateContext templateContext, String variable, String indent);
1616

17+
void dynamicPartial(TemplateContext templateContext, String variable, String indent);
18+
1719
void value(TemplateContext templateContext, String variable, boolean encoded);
1820

1921
void write(TemplateContext templateContext, String text);

compiler/src/main/java/com/github/mustachejava/codes/DefaultCode.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class DefaultCode implements Code, Cloneable {
3131
protected final boolean returnThis;
3232
protected final Binding binding;
3333
protected final DefaultMustacheFactory df;
34+
protected final boolean dynamic;
3435

3536
@SuppressWarnings({"CloneDoesntCallSuperClone", "CloneDoesntDeclareCloneNotSupportedException"})
3637
public Object clone() {
@@ -79,7 +80,13 @@ public DefaultCode(TemplateContext tc, DefaultMustacheFactory df, Mustache musta
7980
this.type = type;
8081
this.name = name;
8182
this.tc = tc;
82-
this.binding = oh == null ? null : oh.createBinding(name, tc, this);
83+
if (name != null && name.startsWith("*")) {
84+
this.binding = oh == null ? null : oh.createBinding(name.substring(1), tc, this);
85+
this.dynamic = true;
86+
} else {
87+
this.binding = oh == null ? null : oh.createBinding(name, tc, this);
88+
this.dynamic = false;
89+
}
8390
this.returnThis = ".".equals(name);
8491
}
8592

@@ -142,6 +149,12 @@ public Object get(List<Object> scopes) {
142149
return length == 0 ? null : scopes.get(length - 1);
143150
}
144151
try {
152+
if (dynamic) {
153+
// We need to create a new binding each time, as the name is dynamic
154+
String dynamicName = (String) binding.get(scopes);
155+
// TODO: cache these bindings
156+
return oh.createBinding(dynamicName, tc, this).get(scopes);
157+
}
145158
return binding.get(scopes);
146159
} catch (MustacheException e) {
147160
e.setContext(tc);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.github.mustachejava.codes;
2+
3+
import com.github.mustachejava.DefaultMustacheFactory;
4+
import com.github.mustachejava.TemplateContext;
5+
6+
import java.io.Writer;
7+
import java.util.List;
8+
import java.util.concurrent.ConcurrentHashMap;
9+
import java.util.concurrent.ConcurrentMap;
10+
11+
public class DynamicPartialCode extends DefaultCode {
12+
public DynamicPartialCode(TemplateContext tc, DefaultMustacheFactory df, String name) {
13+
super(tc, df, null, name, ">*");
14+
}
15+
16+
private final ConcurrentMap<String, PartialCode> partialCodeMap = new ConcurrentHashMap<>();
17+
18+
@Override
19+
public Writer execute(Writer writer, List<Object> scopes) {
20+
String partialName = (String) binding.get(scopes);
21+
if (partialName == null) {
22+
return appendText(writer);
23+
}
24+
PartialCode partialCode = partialCodeMap.computeIfAbsent(partialName, name -> {
25+
PartialCode pc = new PartialCode(tc, df, partialName);
26+
pc.append(appended);
27+
pc.init();
28+
return pc;
29+
});
30+
return partialCode.execute(writer, scopes);
31+
}
32+
}

compiler/src/test/java/com/github/mustachejava/FullSpecTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public void lambdas() {
4545
public void inheritance() throws IOException {
4646
}
4747

48+
@Override
49+
@Test
50+
@Ignore("not ready yet")
51+
public void dynamicnames() {
52+
}
4853

4954
@Override
5055
protected DefaultMustacheFactory createMustacheFactory(final JsonNode test) {

compiler/src/test/java/com/github/mustachejava/SpecTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public void inheritance() throws IOException {
5858
run(getSpec("~inheritance.yml"));
5959
}
6060

61+
@Test
62+
public void dynamicnames() throws IOException {
63+
run(getSpec("~dynamic-names.yml"));
64+
}
65+
6166
private void run(JsonNode spec) {
6267
int fail = 0;
6368
int success = 0;

0 commit comments

Comments
 (0)