You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The refactorings undergone by the Template Resolution API (#419) and Context API (#420) offered the possibility of performing an additional refactoring, this time on the Message Resolution API (package org.thymeleaf.messageresolver).
The Message Resolution API in Thymeleaf 2.1 suffered from two main issues:
No possibility to specify externalized messages for inserted fragments. When an A.html template inserted a fragment from another B.html template, externalized messages could only be resolved from A.properties and never B.properties. Note this affected non-Spring enabled applications only, given Spring-enabled applications normally delegate message resolution entirely to Spring via the Spring MessageSources.
No possibility to customize what should be shown when a message was not found in any of the message resolvers, something the new API knows as absent message representation.
Both were unresolvable problems in 2.1, as it was the very architecture of the message resolution API that prevented any of these features from being implemented.
Thymeleaf 3.0 however modifies the ITemplateResolver interface, so that it looks like this:
So message resolvers now have the opportunity to define not only how a specific message should be resolved, but also what representation should be used for signaling that a message is not found in any of the existing resource bundles.
Also, note that message resolution can be done based on two different pieces of information:
Context, by using the ITemplateContext passed as parameter. Normally, this is used for obtaining the name of the template being processed and using that name for finding the suitable resource bundle.
Origin, by using the Class<?> passed as a parameter, which enables IMessageResolver implementations to perform message lookups specific to processors, pre-/post-processors, or any other template processing structure, without the result depending on the template being processed.
Implementations of IMessageResolver will choose to use both mechanism, one of them, or maybe none.
Message Resolvers will be queried for messages according to their order property. If all the configured message resolvers return null, then the same order will be used for querying them for an absent message representation.
Thymeleaf 3.0, just like 2.1, offers two implementations of IMessageResolver:
StandardMessageResolver, used by default in non-Spring-enabled applications, which will look for .properties files with the same names as the templates it resolves.
SpringMessageResolver, used by default in Spring-enabled applications, which will simply delegate to the Spring configured MessageSource beans, so that Spring is left in complete control of the application's resource bundles.
Improvements on StandardMessageResolver
The org.thymeleaf.messageresolver.StandardMessageResolver class is the basic implementation of IMessageResolver, and it has been improved in Thymeleaf 3.0 so that it allows a greater flexibility for message resolution.
It works like this:
First, for template-based message resolution, it will examine the whole stack of nested template resolutions (so that files for fragments are taken into account, see [MAJOR FEAT] Refactoring of the Context API #420) and will try to find files with the same name as the template, ending in .properties (e.g. main.html -> main.properties). This will be done starting from the first-level template and going towards the most specific fragment template, so that the templates that insert a fragment have the possibility to overwrite the messages specified for that fragment by default if needed.
Note these message files will be resolved as relative resources using the same template resolution mechanism used for the templates themselves (see [MAJOR FEAT] Refactoring of the Template Resolution API #419). So if a template file was retrieved using an HTTP URL, equivalent HTTP URLs will be called for trying to access that template's resources.
For each of these templates, several resource bundle files will be examined. For example, a message in template /WEB-INF/templates/home.html for locale gl_ES-gheada (gl = language, ES = country, gheada = variant) would be looked for in .properties files in the following sequence:
/WEB-INF/templates/home_gl_ES-gheada.properties
/WEB-INF/templates/home_gl_ES.properties
/WEB-INF/templates/home_gl.properties
/WEB-INF/templates/home.properties
If no message is found using this mechanism, origin-based message resolution will be attempted. This will allow the resolution of messages from .properties files living in the classpath (and only in the classpath) in files corresponding with the names of the classes being used as origin. For example, a processor called my.company.processor.SomeDataProcessor using its own class as origin will be able to resolve messages from a my/company/processor/SomeDataProcessor_gl_ES.properties file in the classpath.
Also, if a message is not found for the exact class, resolution will be tried for each of the superclasses this my.company.processor.SomeDataProcessor class extends, until a suitable message is found, or no more superclasses (except java.lang.Object) exist.
Finally, resolution will be tried using the default messages specified directly at the StandardMessageResolver object by means of its setDefaultMessages(Properties) and addDefaultMessage(String, String) methods.
Finally, note that resource bundles obtained using the template-based resolution mechanism will be cached only if the template they refer to was resolved as cacheable by its Template Resolver. Resource bundles obtained using the origin-based resolution will, in contrast, be always cached.
Improvements on SpringMessageResolver
The org.thymeleaf.spring3|spring4.messageresolver.SpringMessageResolver class has also been slightly improved in Thymeleaf 3.0, so that now after delegating to Spring's MessageSource mechanisms the resolution of externalized messages it will also try an origin-based resolution operation completely analogous to the one performed by StandardMessageResolver, as explained above.
This should allow processors, pre-/post-processors, etc. to be packaged in extension libraries as .jar files along with their .properties resource bundles, and make them usable both in Spring-enabled and non-Spring-enabled applications.
The text was updated successfully, but these errors were encountered:
The refactorings undergone by the Template Resolution API (#419) and Context API (#420) offered the possibility of performing an additional refactoring, this time on the Message Resolution API (package
org.thymeleaf.messageresolver
).The Message Resolution API in Thymeleaf 2.1 suffered from two main issues:
A.html
template inserted a fragment from anotherB.html
template, externalized messages could only be resolved fromA.properties
and neverB.properties
. Note this affected non-Spring enabled applications only, given Spring-enabled applications normally delegate message resolution entirely to Spring via the SpringMessageSource
s.Both were unresolvable problems in 2.1, as it was the very architecture of the message resolution API that prevented any of these features from being implemented.
Thymeleaf 3.0 however modifies the
ITemplateResolver
interface, so that it looks like this:So message resolvers now have the opportunity to define not only how a specific message should be resolved, but also what representation should be used for signaling that a message is not found in any of the existing resource bundles.
Also, note that message resolution can be done based on two different pieces of information:
ITemplateContext
passed as parameter. Normally, this is used for obtaining the name of the template being processed and using that name for finding the suitable resource bundle.Class<?>
passed as a parameter, which enablesIMessageResolver
implementations to perform message lookups specific to processors, pre-/post-processors, or any other template processing structure, without the result depending on the template being processed.Implementations of
IMessageResolver
will choose to use both mechanism, one of them, or maybe none.Message Resolvers will be queried for messages according to their
order
property. If all the configured message resolvers returnnull
, then the same order will be used for querying them for an absent message representation.Thymeleaf 3.0, just like 2.1, offers two implementations of
IMessageResolver
:StandardMessageResolver
, used by default in non-Spring-enabled applications, which will look for.properties
files with the same names as the templates it resolves.SpringMessageResolver
, used by default in Spring-enabled applications, which will simply delegate to the Spring configuredMessageSource
beans, so that Spring is left in complete control of the application's resource bundles.Improvements on
StandardMessageResolver
The
org.thymeleaf.messageresolver.StandardMessageResolver
class is the basic implementation ofIMessageResolver
, and it has been improved in Thymeleaf 3.0 so that it allows a greater flexibility for message resolution.It works like this:
.properties
(e.g.main.html
->main.properties
). This will be done starting from the first-level template and going towards the most specific fragment template, so that the templates that insert a fragment have the possibility to overwrite the messages specified for that fragment by default if needed./WEB-INF/templates/home.html
for localegl_ES-gheada
(gl
= language,ES
= country,gheada
= variant) would be looked for in.properties
files in the following sequence:/WEB-INF/templates/home_gl_ES-gheada.properties
/WEB-INF/templates/home_gl_ES.properties
/WEB-INF/templates/home_gl.properties
/WEB-INF/templates/home.properties
.properties
files living in the classpath (and only in the classpath) in files corresponding with the names of the classes being used as origin. For example, a processor calledmy.company.processor.SomeDataProcessor
using its own class asorigin
will be able to resolve messages from amy/company/processor/SomeDataProcessor_gl_ES.properties
file in the classpath.my.company.processor.SomeDataProcessor
class extends, until a suitable message is found, or no more superclasses (exceptjava.lang.Object
) exist.StandardMessageResolver
object by means of itssetDefaultMessages(Properties)
andaddDefaultMessage(String, String)
methods.Finally, note that resource bundles obtained using the template-based resolution mechanism will be cached only if the template they refer to was resolved as cacheable by its Template Resolver. Resource bundles obtained using the origin-based resolution will, in contrast, be always cached.
Improvements on
SpringMessageResolver
The
org.thymeleaf.spring3|spring4.messageresolver.SpringMessageResolver
class has also been slightly improved in Thymeleaf 3.0, so that now after delegating to Spring'sMessageSource
mechanisms the resolution of externalized messages it will also try an origin-based resolution operation completely analogous to the one performed byStandardMessageResolver
, as explained above.This should allow processors, pre-/post-processors, etc. to be packaged in extension libraries as
.jar
files along with their.properties
resource bundles, and make them usable both in Spring-enabled and non-Spring-enabled applications.The text was updated successfully, but these errors were encountered: