From c45cda111a28320dc64a43e14d329e3378bd7767 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 25 Sep 2024 15:59:39 +0200 Subject: [PATCH] Qute: improve docs/javadoc about value resolvers ordering --- docs/src/main/asciidoc/qute-reference.adoc | 11 ++++++++++- .../java/io/quarkus/qute/TemplateExtension.java | 5 +++++ .../main/java/io/quarkus/qute/ValueResolver.java | 13 ++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/qute-reference.adoc b/docs/src/main/asciidoc/qute-reference.adoc index ec2baa1116b13c..5cdeab97b1833d 100644 --- a/docs/src/main/asciidoc/qute-reference.adoc +++ b/docs/src/main/asciidoc/qute-reference.adoc @@ -335,7 +335,7 @@ You can learn more about virtual methods in the <> is used. The first part of the expression is always resolved against the <>. If no result is found for the first part, it's resolved against the parent context object (if available). For an expression that starts with a namespace the current context object is found using all the available ``NamespaceResolver``s. @@ -1451,6 +1451,11 @@ NOTE: The template rendering is divided in two phases. During the first phase, w ==== Value Resolvers Value resolvers are used when evaluating expressions. +First the resolvers that apply to the given `EvalContext` are filtered. +Then the resolver with _highest priority_ is used to resolve the data. +If a `io.quarkus.qute.Results.NotFound` object is returned then the next available resolver is used instead. +However, `null` return value is considered a valid result. + A custom `io.quarkus.qute.ValueResolver` can be registered programmatically via `EngineBuilder.addValueResolver()`. .`ValueResolver` Builder Example @@ -1462,6 +1467,10 @@ engineBuilder.addValueResolver(ValueResolver.builder() .build()); ---- +TIP: In Quarkus, the <> annotation can be used to register a `ValueResolver` implemented as a CDI bean. + +NOTE: Keep in mind that the reflection-based value resolver has priority `-1` and the max priority value for resolvers generated from <> and <> is `10`. + [[template-locator]] ==== Template Locator diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateExtension.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateExtension.java index cc2c958ec0df88..5e79e687e7ad6b 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateExtension.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateExtension.java @@ -125,8 +125,13 @@ String matchRegex() default ""; /** + * Value resolvers with higher priority take precedence. + *

+ * Keep in mind that the reflection-based value resolver has priority {@code -1} and the max priority value for + * resolvers generated from {@link TemplateData} and type-safe expressions is {@code 10}. * * @return the priority used by the generated value resolver + * @see ValueResolver#getPriority() */ int priority() default DEFAULT_PRIORITY; diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/ValueResolver.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/ValueResolver.java index 1a09e1f36a8fb0..aa3f7c729bb285 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/ValueResolver.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/ValueResolver.java @@ -4,7 +4,8 @@ * Value resolvers are used when evaluating expressions. *

* First the resolvers that apply to the given {@link EvalContext} are filtered. Then the resolver with highest priority is used - * to resolve the data. If {@link Results#isNotFound(Object)} is returned the next available resolver is tried. + * to resolve the data. If a {@link io.quarkus.qute.Results.NotFound} object is returned then the next available resolver is used instead. However, + * {@code null} return value is considered a valid result. * * @see EvalContext * @see EngineBuilder#addValueResolver(ValueResolver) @@ -12,6 +13,16 @@ */ public interface ValueResolver extends Resolver, WithPriority { + /** + * Value resolvers with higher priority take precedence. + * + * @return the priority value + */ + @Override + default int getPriority() { + return WithPriority.super.getPriority(); + } + /** * * @param context