Skip to content

Commit 3c19a78

Browse files
authored
Merge pull request #46257 from mkouba/issue-46254
Qute: fix template variants for templates with dot in the name
2 parents e303d7b + bfc17f6 commit 3c19a78

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java

+23-11
Original file line numberDiff line numberDiff line change
@@ -2427,21 +2427,33 @@ private void reportFoundInvalidTarget(BuildProducer<ValidationErrorBuildItem> va
24272427
}
24282428

24292429
@BuildStep
2430-
TemplateVariantsBuildItem collectTemplateVariants(List<TemplatePathBuildItem> templatePaths) throws IOException {
2430+
TemplateVariantsBuildItem collectTemplateVariants(List<TemplatePathBuildItem> templatePaths, QuteConfig config)
2431+
throws IOException {
24312432
Set<String> allPaths = templatePaths.stream().map(TemplatePathBuildItem::getPath).collect(Collectors.toSet());
2433+
// Variants are usually used when injecting a template, e.g. @Inject Template foo
2434+
// In this case, the suffix may not specified but the correct template may be selected based on a matching variant
2435+
// For example, the HTTP Accept header may be used to find a matching variant
24322436
// item -> [item.html, item.txt]
2433-
// ItemResource/item -> -> [ItemResource/item.html, ItemResource/item.xml]
2437+
// item.1 -> [item.1.html, item.1.txt]
2438+
// item -> [item.qute.html, item.qute.txt]
2439+
// ItemResource/item -> [ItemResource/item.html, ItemResource/item.xml]
24342440
Map<String, List<String>> baseToVariants = new HashMap<>();
24352441
for (String path : allPaths) {
2436-
int idx = path.indexOf('.');
2437-
if (idx != -1) {
2438-
String base = path.substring(0, idx);
2439-
List<String> variants = baseToVariants.get(base);
2440-
if (variants == null) {
2441-
variants = new ArrayList<>();
2442-
baseToVariants.put(base, variants);
2443-
}
2444-
variants.add(path);
2442+
for (String suffix : config.suffixes()) {
2443+
// Iterate over all supported suffixes and register appropriate base
2444+
// item.1.html -> item.1
2445+
// item.html -> item
2446+
// item.qute.html -> item, item.qute
2447+
// ItemResource/item.xml -> ItemResource/item
2448+
if (path.endsWith(suffix)) {
2449+
String base = path.substring(0, path.length() - (suffix.length() + 1));
2450+
List<String> variants = baseToVariants.get(base);
2451+
if (variants == null) {
2452+
variants = new ArrayList<>();
2453+
baseToVariants.put(base, variants);
2454+
}
2455+
variants.add(path);
2456+
}
24452457
}
24462458
}
24472459
LOGGER.debugf("Template variants found: %s", baseToVariants);

extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/inject/InjectionTest.java

+41-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import static org.junit.jupiter.api.Assertions.assertThrows;
66
import static org.junit.jupiter.api.Assertions.assertTrue;
77

8+
import java.util.List;
9+
810
import jakarta.enterprise.context.Dependent;
911
import jakarta.inject.Inject;
1012

@@ -15,6 +17,9 @@
1517
import io.quarkus.qute.Engine;
1618
import io.quarkus.qute.Location;
1719
import io.quarkus.qute.Template;
20+
import io.quarkus.qute.Variant;
21+
import io.quarkus.qute.runtime.QuteRecorder.QuteContext;
22+
import io.quarkus.qute.runtime.TemplateProducer;
1823
import io.quarkus.test.QuarkusUnitTest;
1924

2025
public class InjectionTest {
@@ -23,20 +28,33 @@ public class InjectionTest {
2328
static final QuarkusUnitTest config = new QuarkusUnitTest()
2429
.withApplicationRoot((jar) -> jar
2530
.addClasses(SimpleBean.class)
26-
.addAsResource(new StringAsset("quarkus.qute.suffixes=txt"), "application.properties")
2731
.addAsResource(new StringAsset("{this}"), "templates/foo.txt")
2832
.addAsResource(new StringAsset("<strong>{this}</strong>"), "templates/foo.qute.html")
29-
.addAsResource(new StringAsset("{@String foo}{this}"), "templates/bars/bar.txt"));
33+
.addAsResource(new StringAsset("{@String foo}{this}"), "templates/bars/bar.txt")
34+
.addAsResource(new StringAsset("Hello {name}!"), "templates/foo.1.html")
35+
.addAsResource(new StringAsset("Hello {name}!"), "templates/foo.1.txt"));
3036

3137
@Inject
3238
SimpleBean simpleBean;
3339

40+
@Inject
41+
QuteContext quteContext;
42+
43+
@Inject
44+
TemplateProducer templateProducer;
45+
3446
@Test
3547
public void testInjection() {
3648
assertNotNull(simpleBean.engine);
3749
assertTrue(simpleBean.engine.locate("foo.txt").isPresent());
50+
// foo.qute.html takes precedence
51+
assertTrue(simpleBean.engine.locate("foo").orElseThrow().getVariant().get().getContentType().equals(Variant.TEXT_HTML));
3852
assertTrue(simpleBean.engine.locate("foo.html").isEmpty());
39-
assertEquals("bar", simpleBean.foo.render("bar"));
53+
assertEquals("bar",
54+
simpleBean.foo.instance()
55+
.setVariant(Variant.forContentType(Variant.TEXT_PLAIN))
56+
.data("bar")
57+
.render());
4058
assertEquals("<strong>bar</strong>", simpleBean.foo2.render("bar"));
4159
assertEquals("bar", simpleBean.bar.render("bar"));
4260

@@ -54,6 +72,25 @@ public void testInjection() {
5472
assertEquals("UTF-8", simpleBean.bar.getVariant().get().getEncoding());
5573
assertNotNull(simpleBean.bar.getGeneratedId());
5674
assertEquals("foo.qute.html", simpleBean.foo2.getId());
75+
assertEquals(Variant.TEXT_HTML, simpleBean.foo2.getVariant().get().getContentType());
76+
List<String> fooVariants = quteContext.getVariants().get("foo");
77+
// foo -> foo.txt, foo.qute.html
78+
assertEquals(2, fooVariants.size());
79+
assertTrue(fooVariants.contains("foo.txt"));
80+
assertTrue(fooVariants.contains("foo.qute.html"));
81+
List<String> fooQuteVariants = quteContext.getVariants().get("foo.qute");
82+
// foo.qute -> foo.qute.html
83+
assertEquals(1, fooQuteVariants.size());
84+
assertTrue(fooVariants.contains("foo.qute.html"));
85+
86+
assertEquals("Hello &lt;strong&gt;Foo&lt;/strong&gt;!", templateProducer.getInjectableTemplate("foo.1").instance()
87+
.setVariant(Variant.forContentType(Variant.TEXT_HTML))
88+
.data("name", "<strong>Foo</strong>")
89+
.render());
90+
assertEquals("Hello <strong>Foo</strong>!", templateProducer.getInjectableTemplate("foo.1").instance()
91+
.setVariant(Variant.forContentType(Variant.TEXT_PLAIN))
92+
.data("name", "<strong>Foo</strong>")
93+
.render());
5794
}
5895

5996
@Dependent
@@ -73,4 +110,4 @@ public static class SimpleBean {
73110

74111
}
75112

76-
}
113+
}

0 commit comments

Comments
 (0)