Skip to content

Commit 1cafe49

Browse files
authored
Merge pull request #8824 from mkouba/issue-8754
Qute - get rid of VariantTemplate and unify func. of injected templates
2 parents a2b3660 + d05b81e commit 1cafe49

File tree

12 files changed

+196
-311
lines changed

12 files changed

+196
-311
lines changed

docs/src/main/asciidoc/qute-reference.adoc

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ If you want to use Qute in your Quarkus application add the following dependency
624624
</dependency>
625625
----
626626

627-
In Quarkus, a preconfigured engine instance is provided and available for injection - a bean with scope `@Singleton`, bean type `io.quarkus.qute.Engine` and qualifier `@Default` is registered automatically.
627+
In Quarkus, a preconfigured engine instance is provided and available for injection - a bean with scope `@ApplicationScoped`, bean type `io.quarkus.qute.Engine` and qualifier `@Default` is registered automatically.
628628
Moreover, all templates located in the `src/main/resources/templates` directory are validated and can be easily injected.
629629

630630
[source,java]
@@ -649,6 +649,29 @@ class MyBean {
649649
<2> The `ResourcePath` qualifier instructs the container to inject a template from a path relative from `src/main/resources/templates`. In this case, the full path is `src/main/resources/templates/detail/items2_v1.html`.
650650
<3> Inject the configured `Engine` instance.
651651

652+
=== Template Variants
653+
654+
Sometimes it's useful to render a specific variant of the template based on the content negotiation.
655+
This can be done by setting a special attribute via `TemplateInstance.setAttribute()`:
656+
657+
[source,java]
658+
----
659+
class MyService {
660+
661+
@Inject
662+
Template items; <1>
663+
664+
@Inject
665+
ItemManager manager;
666+
667+
String renderItems() {
668+
return items.data("items",manager.findItems()).setAttribute(TemplateInstance.SELECTED_VARIANT, new Variant(Locale.getDefault(),"text/html","UTF-8")).render();
669+
}
670+
}
671+
----
672+
673+
NOTE: When using `quarkus-resteasy-qute` the content negotiation is performed automatically. See <<resteasy_integration>>.
674+
652675
=== Injecting Beans Directly In Templates
653676

654677
A CDI bean annotated with `@Named` can be referenced in any template through the `inject` namespace:
@@ -885,6 +908,7 @@ class Item {
885908
----
886909
<1> The generated value resolver knows how to invoke the `BigDecimal.setScale()` method.
887910

911+
[[resteasy_integration]]
888912
=== RESTEasy Integration
889913

890914
If you want to use Qute in your JAX-RS application, you'll need to add the `quarkus-resteasy-qute` extension first.
@@ -931,18 +955,17 @@ public class HelloResource {
931955
<2> `Template.data()` returns a new template instance that can be customized before the actual rendering is triggered. In this case, we put the name value under the key `name`. The data map is accessible during rendering.
932956
<3> Note that we don't trigger the rendering - this is done automatically by a special `ContainerResponseFilter` implementation.
933957

934-
==== Variant Templates
935958

936-
Sometimes it could be useful to render a specific variant of the template based on the content negotiation.
937-
`VariantTemplate` is a perfect match for this use case:
959+
The content negotiation is performed automatically.
960+
The resulting output depends on the `Accept` header received from the client.
938961

939962
[source,java]
940963
----
941964
@Path("/detail")
942965
class DetailResource {
943966
944967
@Inject
945-
VariantTemplate item; <1>
968+
Template item; <1>
946969
947970
@GET
948971
@Produces({ MediaType.TEXT_HTML, MediaType.TEXT_PLAIN })
@@ -952,7 +975,7 @@ class DetailResource {
952975
}
953976
----
954977
<1> Inject a variant template with base path derived from the injected field - `src/main/resources/templates/item`.
955-
<2> The resulting output depends on the `Accept` header received from the client. For `text/plain` the `src/main/resources/templates/item.txt` template is used. For `text/html` the `META-INF/resources/templates/item.html` template is used.
978+
<2> For `text/plain` the `src/main/resources/templates/item.txt` template is used. For `text/html` the `META-INF/resources/templates/item.html` template is used.
956979

957980

958981
=== Development Mode

extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailTemplateInstanceImpl.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package io.quarkus.mailer.runtime;
22

3-
import static io.quarkus.qute.api.VariantTemplate.SELECTED_VARIANT;
4-
import static io.quarkus.qute.api.VariantTemplate.VARIANTS;
5-
63
import java.util.ArrayList;
74
import java.util.HashMap;
85
import java.util.List;
@@ -16,7 +13,6 @@
1613
import io.quarkus.mailer.MailTemplate.MailTemplateInstance;
1714
import io.quarkus.qute.TemplateInstance;
1815
import io.quarkus.qute.Variant;
19-
import io.quarkus.qute.api.VariantTemplate;
2016
import io.smallrye.mutiny.Uni;
2117

2218
class MailTemplateInstanceImpl implements MailTemplate.MailTemplateInstance {
@@ -89,24 +85,22 @@ public MailTemplateInstance data(String key, Object value) {
8985

9086
@Override
9187
public CompletionStage<Void> send() {
92-
if (templateInstance.getAttribute(VariantTemplate.VARIANTS) != null) {
93-
88+
Object variantsAttr = templateInstance.getAttribute(TemplateInstance.VARIANTS);
89+
if (variantsAttr != null) {
9490
List<Result> results = new ArrayList<>();
95-
9691
@SuppressWarnings("unchecked")
97-
List<Variant> variants = (List<Variant>) templateInstance.getAttribute(VARIANTS);
92+
List<Variant> variants = (List<Variant>) variantsAttr;
9893
for (Variant variant : variants) {
9994
if (variant.mediaType.equals(Variant.TEXT_HTML) || variant.mediaType.equals(Variant.TEXT_PLAIN)) {
10095
results.add(new Result(variant,
10196
Uni.createFrom().completionStage(
102-
() -> templateInstance.setAttribute(SELECTED_VARIANT, variant).data(data).renderAsync())));
97+
() -> templateInstance.setAttribute(TemplateInstance.SELECTED_VARIANT, variant).data(data)
98+
.renderAsync())));
10399
}
104100
}
105-
106101
if (results.isEmpty()) {
107102
throw new IllegalStateException("No suitable template variant found");
108103
}
109-
110104
List<Uni<String>> unis = results.stream().map(Result::getValue).collect(Collectors.toList());
111105
return Uni.combine().all().unis(unis)
112106
.combinedWith(combine(results))

extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailTemplateProducer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import org.jboss.logging.Logger;
1515

1616
import io.quarkus.mailer.MailTemplate;
17+
import io.quarkus.qute.Template;
1718
import io.quarkus.qute.api.ResourcePath;
18-
import io.quarkus.qute.api.VariantTemplate;
1919

2020
@Singleton
2121
public class MailTemplateProducer {
@@ -26,7 +26,7 @@ public class MailTemplateProducer {
2626
MutinyMailerImpl mailer;
2727

2828
@Any
29-
Instance<VariantTemplate> template;
29+
Instance<Template> template;
3030

3131
@Produces
3232
MailTemplate getDefault(InjectionPoint injectionPoint) {

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

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@
8686
import io.quarkus.qute.UserTagSectionHelper;
8787
import io.quarkus.qute.Variant;
8888
import io.quarkus.qute.api.ResourcePath;
89-
import io.quarkus.qute.api.VariantTemplate;
9089
import io.quarkus.qute.deployment.TemplatesAnalysisBuildItem.TemplateAnalysis;
9190
import io.quarkus.qute.deployment.TypeCheckExcludeBuildItem.Check;
9291
import io.quarkus.qute.deployment.TypeInfos.Info;
@@ -98,7 +97,6 @@
9897
import io.quarkus.qute.runtime.QuteRecorder;
9998
import io.quarkus.qute.runtime.QuteRecorder.QuteContext;
10099
import io.quarkus.qute.runtime.TemplateProducer;
101-
import io.quarkus.qute.runtime.VariantTemplateProducer;
102100
import io.quarkus.qute.runtime.extensions.CollectionTemplateExtensions;
103101
import io.quarkus.qute.runtime.extensions.MapTemplateExtensions;
104102
import io.quarkus.qute.runtime.extensions.NumberTemplateExtensions;
@@ -108,11 +106,8 @@ public class QuteProcessor {
108106
private static final Logger LOGGER = Logger.getLogger(QuteProcessor.class);
109107

110108
public static final DotName RESOURCE_PATH = DotName.createSimple(ResourcePath.class.getName());
111-
112109
public static final DotName TEMPLATE = DotName.createSimple(Template.class.getName());
113110

114-
public static final DotName VARIANT_TEMPLATE = DotName.createSimple(VariantTemplate.class.getName());
115-
116111
static final DotName ITERABLE = DotName.createSimple(Iterable.class.getName());
117112
static final DotName ITERATOR = DotName.createSimple(Iterator.class.getName());
118113
static final DotName STREAM = DotName.createSimple(Stream.class.getName());
@@ -164,7 +159,7 @@ void processTemplateErrors(TemplatesAnalysisBuildItem analysis, List<IncorrectEx
164159
AdditionalBeanBuildItem additionalBeans() {
165160
return AdditionalBeanBuildItem.builder()
166161
.setUnremovable()
167-
.addBeanClasses(EngineProducer.class, TemplateProducer.class, VariantTemplateProducer.class, ResourcePath.class,
162+
.addBeanClasses(EngineProducer.class, TemplateProducer.class, ResourcePath.class,
168163
Template.class, TemplateInstance.class, CollectionTemplateExtensions.class,
169164
MapTemplateExtensions.class, NumberTemplateExtensions.class)
170165
.build();
@@ -682,24 +677,6 @@ void validateTemplateInjectionPoints(QuteConfig config, List<TemplatePathBuildIt
682677
new IllegalStateException("No template found for " + injectionPoint.getTargetInfo())));
683678
}
684679
}
685-
686-
} else if (injectionPoint.getRequiredType().name().equals(VARIANT_TEMPLATE)) {
687-
688-
AnnotationInstance resourcePath = injectionPoint.getRequiredQualifier(RESOURCE_PATH);
689-
String name;
690-
if (resourcePath != null) {
691-
name = resourcePath.value().asString();
692-
} else if (injectionPoint.hasDefaultedQualifier()) {
693-
name = getName(injectionPoint);
694-
} else {
695-
name = null;
696-
}
697-
if (name != null) {
698-
if (filePaths.stream().noneMatch(path -> path.endsWith(name))) {
699-
validationErrors.produce(new ValidationErrorBuildItem(
700-
new IllegalStateException("No variant template found for " + injectionPoint.getTargetInfo())));
701-
}
702-
}
703680
}
704681
}
705682
}
@@ -721,7 +698,7 @@ TemplateVariantsBuildItem collectTemplateVariants(List<TemplatePathBuildItem> te
721698
variants.add(path);
722699
}
723700
}
724-
LOGGER.debugf("Variant templates found: %s", baseToVariants);
701+
LOGGER.debugf("Template variants found: %s", baseToVariants);
725702
return new TemplateVariantsBuildItem(baseToVariants);
726703
}
727704

extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/VariantTemplateTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import org.junit.jupiter.api.Test;
1212
import org.junit.jupiter.api.extension.RegisterExtension;
1313

14+
import io.quarkus.qute.Template;
1415
import io.quarkus.qute.TemplateInstance;
1516
import io.quarkus.qute.Variant;
16-
import io.quarkus.qute.api.VariantTemplate;
1717
import io.quarkus.test.QuarkusUnitTest;
1818

1919
public class VariantTemplateTest {
@@ -31,17 +31,17 @@ public class VariantTemplateTest {
3131
@Test
3232
public void testRendering() {
3333
TemplateInstance rendering = simpleBean.foo.instance().data("bar");
34-
rendering.setAttribute(VariantTemplate.SELECTED_VARIANT, new Variant(null, "text/plain", null));
34+
rendering.setAttribute(TemplateInstance.SELECTED_VARIANT, new Variant(null, "text/plain", null));
3535
assertEquals("bar", rendering.render());
36-
rendering.setAttribute(VariantTemplate.SELECTED_VARIANT, new Variant(null, "text/html", null));
36+
rendering.setAttribute(TemplateInstance.SELECTED_VARIANT, new Variant(null, "text/html", null));
3737
assertEquals("<strong>bar</strong>", rendering.render());
3838
}
3939

4040
@Dependent
4141
public static class SimpleBean {
4242

4343
@Inject
44-
VariantTemplate foo;
44+
Template foo;
4545

4646
}
4747

extensions/qute/runtime/src/main/java/io/quarkus/qute/api/VariantTemplate.java

Lines changed: 0 additions & 22 deletions
This file was deleted.

extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/EngineProducer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ static Variant guessVariant(String path) {
192192
int suffixIdx = path.lastIndexOf('.');
193193
if (suffixIdx != -1) {
194194
String suffix = path.substring(suffixIdx);
195-
return new Variant(null, VariantTemplateProducer.parseMediaType(suffix), null);
195+
return new Variant(null, TemplateProducer.parseMediaType(suffix), null);
196196
}
197197
return null;
198198
}

0 commit comments

Comments
 (0)