Skip to content

Commit

Permalink
Qute: fix template variants for templates with dot in the name
Browse files Browse the repository at this point in the history
  • Loading branch information
mkouba committed Feb 13, 2025
1 parent 046dc99 commit bfc17f6
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2427,21 +2427,33 @@ private void reportFoundInvalidTarget(BuildProducer<ValidationErrorBuildItem> va
}

@BuildStep
TemplateVariantsBuildItem collectTemplateVariants(List<TemplatePathBuildItem> templatePaths) throws IOException {
TemplateVariantsBuildItem collectTemplateVariants(List<TemplatePathBuildItem> templatePaths, QuteConfig config)
throws IOException {
Set<String> allPaths = templatePaths.stream().map(TemplatePathBuildItem::getPath).collect(Collectors.toSet());
// Variants are usually used when injecting a template, e.g. @Inject Template foo
// In this case, the suffix may not specified but the correct template may be selected based on a matching variant
// For example, the HTTP Accept header may be used to find a matching variant
// item -> [item.html, item.txt]
// ItemResource/item -> -> [ItemResource/item.html, ItemResource/item.xml]
// item.1 -> [item.1.html, item.1.txt]
// item -> [item.qute.html, item.qute.txt]
// ItemResource/item -> [ItemResource/item.html, ItemResource/item.xml]
Map<String, List<String>> baseToVariants = new HashMap<>();
for (String path : allPaths) {
int idx = path.indexOf('.');
if (idx != -1) {
String base = path.substring(0, idx);
List<String> variants = baseToVariants.get(base);
if (variants == null) {
variants = new ArrayList<>();
baseToVariants.put(base, variants);
}
variants.add(path);
for (String suffix : config.suffixes()) {
// Iterate over all supported suffixes and register appropriate base
// item.1.html -> item.1
// item.html -> item
// item.qute.html -> item, item.qute
// ItemResource/item.xml -> ItemResource/item
if (path.endsWith(suffix)) {
String base = path.substring(0, path.length() - (suffix.length() + 1));
List<String> variants = baseToVariants.get(base);
if (variants == null) {
variants = new ArrayList<>();
baseToVariants.put(base, variants);
}
variants.add(path);
}
}
}
LOGGER.debugf("Template variants found: %s", baseToVariants);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.List;

import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

Expand All @@ -15,6 +17,9 @@
import io.quarkus.qute.Engine;
import io.quarkus.qute.Location;
import io.quarkus.qute.Template;
import io.quarkus.qute.Variant;
import io.quarkus.qute.runtime.QuteRecorder.QuteContext;
import io.quarkus.qute.runtime.TemplateProducer;
import io.quarkus.test.QuarkusUnitTest;

public class InjectionTest {
Expand All @@ -23,20 +28,33 @@ public class InjectionTest {
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(SimpleBean.class)
.addAsResource(new StringAsset("quarkus.qute.suffixes=txt"), "application.properties")
.addAsResource(new StringAsset("{this}"), "templates/foo.txt")
.addAsResource(new StringAsset("<strong>{this}</strong>"), "templates/foo.qute.html")
.addAsResource(new StringAsset("{@String foo}{this}"), "templates/bars/bar.txt"));
.addAsResource(new StringAsset("{@String foo}{this}"), "templates/bars/bar.txt")
.addAsResource(new StringAsset("Hello {name}!"), "templates/foo.1.html")
.addAsResource(new StringAsset("Hello {name}!"), "templates/foo.1.txt"));

@Inject
SimpleBean simpleBean;

@Inject
QuteContext quteContext;

@Inject
TemplateProducer templateProducer;

@Test
public void testInjection() {
assertNotNull(simpleBean.engine);
assertTrue(simpleBean.engine.locate("foo.txt").isPresent());
// foo.qute.html takes precedence
assertTrue(simpleBean.engine.locate("foo").orElseThrow().getVariant().get().getContentType().equals(Variant.TEXT_HTML));
assertTrue(simpleBean.engine.locate("foo.html").isEmpty());
assertEquals("bar", simpleBean.foo.render("bar"));
assertEquals("bar",
simpleBean.foo.instance()
.setVariant(Variant.forContentType(Variant.TEXT_PLAIN))
.data("bar")
.render());
assertEquals("<strong>bar</strong>", simpleBean.foo2.render("bar"));
assertEquals("bar", simpleBean.bar.render("bar"));

Expand All @@ -54,6 +72,25 @@ public void testInjection() {
assertEquals("UTF-8", simpleBean.bar.getVariant().get().getEncoding());
assertNotNull(simpleBean.bar.getGeneratedId());
assertEquals("foo.qute.html", simpleBean.foo2.getId());
assertEquals(Variant.TEXT_HTML, simpleBean.foo2.getVariant().get().getContentType());
List<String> fooVariants = quteContext.getVariants().get("foo");
// foo -> foo.txt, foo.qute.html
assertEquals(2, fooVariants.size());
assertTrue(fooVariants.contains("foo.txt"));
assertTrue(fooVariants.contains("foo.qute.html"));
List<String> fooQuteVariants = quteContext.getVariants().get("foo.qute");
// foo.qute -> foo.qute.html
assertEquals(1, fooQuteVariants.size());
assertTrue(fooVariants.contains("foo.qute.html"));

assertEquals("Hello &lt;strong&gt;Foo&lt;/strong&gt;!", templateProducer.getInjectableTemplate("foo.1").instance()
.setVariant(Variant.forContentType(Variant.TEXT_HTML))
.data("name", "<strong>Foo</strong>")
.render());
assertEquals("Hello <strong>Foo</strong>!", templateProducer.getInjectableTemplate("foo.1").instance()
.setVariant(Variant.forContentType(Variant.TEXT_PLAIN))
.data("name", "<strong>Foo</strong>")
.render());
}

@Dependent
Expand All @@ -73,4 +110,4 @@ public static class SimpleBean {

}

}
}

0 comments on commit bfc17f6

Please # to comment.