Table of contents15 Configuration Details
15.1 Resolver Templates
For our virtual grocery store Thymes, we chose an ITemplateResolver implementation called ServletContextTemplateResolver, which allowed us to get templates as resources from the servlet context.
In addition to providing the ability to create your own template resolver, implementing the ITemplateResolver, Thymeleaf includes four implementations out of the box:
- org.thymeleaf.templateresolver.ClassLoaderTemplateResolver , which finds templates as class loader resources, for example:
')
return Thread.currentThread().getContextClassLoader().getResourceAsStream(template);
- org.thymeleaf.templateresolver.FileTemplateResolver , which finds templates as files from the file system, for example:
return new FileInputStream(new File(template));
- org.thymeleaf.templateresolver.UrlTemplateResolver , which finds patterns as URLs (even non-local), for example:
return (new URL(template)).openStream();
- org.thymeleaf.templateresolver.StringTemplateResolver , which finds templates directly, because the String is specified as a template (or a template name, which in this case, obviously, is much more than a simple name):
return new StringReader(templateName);
All predefined ITemplateResolver implementations allow you to use the same set of configuration parameters, which include:
- Prefix and suffix (as already seen):
templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".html");
- Template aliases that allow you to use template names that do not correspond to file names. If there is a suffix / prefix and an alias, the alias will be applied before the prefix / suffix:
templateResolver.addTemplateAlias("adminHome","profiles/admin/home"); templateResolver.setTemplateAliases(aliasesMap);
- Encoding used when reading templates:
templateResolver.setEncoding("UTF-8");
- Template mode used:
- The default mode for the template cache and patterns is to determine whether specific templates are cacheable or not:
- TTL in milliseconds for parsing template cache entries created in this template resolver. If not specified, the only way to delete a record from the cache is LRU (the maximum cache size is exceeded, and the record will be the oldest).
Thymeleaf + Spring integration packs offer a SpringResourceTemplateResolver implementation that uses the entire Spring framework to access and read resources in applications and which is the recommended implementation for applications that support Spring.
Chain of resolvers patternsIn addition, the template engine can specify multiple template crawlers, in which case the order can be set between them to search for a template, so if the first cannot find the template, the second is requested and so on:
ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver(); classLoaderTemplateResolver.setOrder(Integer.valueOf(1)); ServletContextTemplateResolver servletContextTemplateResolver = new ServletContextTemplateResolver(servletContext); servletContextTemplateResolver.setOrder(Integer.valueOf(2)); templateEngine.addTemplateResolver(classLoaderTemplateResolver); templateEngine.addTemplateResolver(servletContextTemplateResolver);
When multiple resolver patterns are used, it is recommended that
patterns be specified for each pattern recognizer, so that Thymeleaf can quickly cancel these pattern-based resolvers that are not designed to find a pattern, improving performance. This is not a requirement, but a recommendation:
ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver(); classLoaderTemplateResolver.setOrder(Integer.valueOf(1));
If these resolvable patterns are not specified, we will rely on the specific capabilities of each of the ITemplateResolver implementations we created. Note that not all implementations can determine the existence of a pattern before its resolving and therefore can always consider a pattern as resolvable and interrupt the search chain (not allowing other resolvers to check the same pattern).
All ITemplateResolver implementations that are part of the Thymeleaf core include a mechanism that allows us to force resolvers to really check if a resource exists before it is found. This is the
checkExistence flag, which works like:
ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver(); classLoaderTemplateResolver.setOrder(Integer.valueOf(1)); classLoaderTempalteResolver.setCheckExistence(true);
This
checkExistence flag causes the resolver to perform a real check for the existence of the resource during the search phase (and let the next search be carried out in a chain if the current check returns false). While this may seem like a good solution, in most cases it will mean dual access to the resource itself (once to check for existence, at another time to read it) and can be a performance problem in some scenarios, for example, “remote” template-based resources URLs are a potential performance problem, which in any case can be greatly mitigated by using the template cache (in this case, the templates will be searched only when they are first accessed).
15.2 Message Resolvers
We did not explicitly specify the Message Resolver implementation for our Grocery application, and, as explained earlier, this meant that the implementation used was the org.thymeleaf.messageresolver.StandardMessageResolver object.
StandardMessageResolver is a standard implementation of the IMessageResolver interface, but we could create our own, if you wanted, adapted to the specific needs of our application.
Thymeleaf + Spring integration packages offer a default implementation of
IMessageResolver , which uses the standard Spring method to receive external messages using MessageSource components declared in the context of the Spring Application Context.
Standard Message ResolverSo, how does the
StandardMessageResolver of messages requested by a particular template look like?
If the template name is “home” and it is in /WEB-INF/templates/home.html, and the requested language is gl_ES, then this recognizer will look for messages in the following files in the following order:
/WEB-INF/templates/home_gl_ES.properties /WEB-INF/templates/home_gl.properties /WEB-INF/templates/home.properties
See the StandardMessageResolver class JavaDoc documentation for more details on how the full message search engine works.
Configuring the Message FinderWhat if we want to add a message mapper (or more) to the template engine? This is easy:
And why do we want to have more than one message finder? For the same reason as the template crawler: the message organizers are ordered, and if the first cannot find a specific message, the second will be requested, then the third, and so on.
15.3 Conversion Services
The transformation service, which allows us to perform data conversion and formatting operations using the double-brace syntax
($ {{...}}) , is actually an element of the standard dialect, and not the Thymeleaf template mechanism itself.
Thus, the way to configure it is to configure the custom implementation of the
IStandardConversionService interface directly in the StandardDialect instance, which is configured in the template engine. More details:
IStandardConversionService customConversionService = ... StandardDialect dialect = new StandardDialect(); dialect.setConversionService(customConversionService); templateEngine.setDialect(dialect);
Note that the
thymeleaf-spring3 and
thymeleaf-spring4 packages contain SpringStandardDialect, and this dialect is already pre-configured with the implementation of
IStandardConversionService , which integrates Spring’s own transformation service infrastructure into Thymeleaf.
15.4 Logging
Thymeleaf pays great attention to event logging and is always trying to provide the maximum amount of useful information through its logging interface.
The logging library used is
slf4j , which actually acts as a bridge for any logging implementation that we could use in our application (for example, log4j).
In the Thymeleaf classes
, TRACE, DEBUG and INFO data will be recorded, depending on the level of detail we want, and besides general logging, it will use three special loggers associated with the TemplateEngine class, which we can configure separately for different purposes:
An example configuration for a Thymeleaf registration infrastructure using log4j might be:
log4j.logger.org.thymeleaf=DEBUG log4j.logger.org.thymeleaf.TemplateEngine.CONFIG=TRACE log4j.logger.org.thymeleaf.TemplateEngine.TIMER=TRACE log4j.logger.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=TRACE