Thymeleaf Tutorial: Chapter 15. Configuration Details

  • Tutorial
Table of contents

15 Configuration Details


15.1 Resolver Templates


For our virtual grocery store Thymes, we chose an implementation of ITemplateResolver 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 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 ones), for example:

    return (new URL(template)).openStream();
  • org.thymeleaf.templateresolver.StringTemplateResolver , which finds templates directly, since String is specified as a template (or the name of the template, which in this case is obviously 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 match 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:

    // Default is HTML
        templateResolver.setTemplateMode("XML");
  • The default mode for the pattern cache and patterns is to determine whether particular patterns are cacheable or not:

    // Default is true
        templateResolver.setCacheable(false);
        templateResolver.getCacheablePatternSpec().addPattern("/users/*");
  • TTL in milliseconds for parsed template cache entries created in this template resolver. If not specified, the only way to delete a cache entry is LRU (the maximum cache size has been exceeded and the record will be the oldest).

    // По умолчанию нет TTL (только LRU удаляет записи)
        templateResolver.setCacheTTLMs(60000L);

Thymeleaf + Spring integration packages offer a SpringResourceTemplateResolver implementation that uses the entire Spring infrastructure to access and read resources in applications and which is the recommended implementation in Spring-enabled applications.

The pattern resolvers chain

In addition, the pattern engine can specify several pattern finders, in which case the order can be set between them to search for a pattern, so if the first cannot find the pattern, 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 templates are used, it is recommended that you specify patterns for each pattern recognizer so that Thymeleaf can quickly undo these pattern resolvers that are not designed to search for a pattern, increasing performance. This is not a requirement, but a recommendation:

ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver();
classLoaderTemplateResolver.setOrder(Integer.valueOf(1));
// У этого загрузчика классов даже не будут запрошены классы, не соответствующие этим паттернам
classLoaderTemplateResolver.getResolvablePatternSpec().addPattern("/layout/*.html");
classLoaderTemplateResolver.getResolvablePatternSpec().addPattern("/menu/*.html");
ServletContextTemplateResolver servletContextTemplateResolver = 
        new ServletContextTemplateResolver(servletContext);
servletContextTemplateResolver.setOrder(Integer.valueOf(2));

If these resolvable templates are not specified, we will rely on the specific capabilities of each of the ITemplateResolver implementations we create. Please note that not all implementations can determine the existence of a template before resolving it and therefore can always consider a template as resolvable and interrupt the search chain (not allowing other resolvers to check the same template).

All implementations of ITemplateResolver that are part of the Thymeleaf kernel include a mechanism that allows us to force resolvers to really check if a resource exists before considering it to be found. This is the checkExistence flag , which works like:

ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver();
classLoaderTemplateResolver.setOrder(Integer.valueOf(1));
classLoaderTempalteResolver.setCheckExistence(true);

This checkExistence flag forces the resolver to perform a real check on the existence of the resource during the search phase (and let the next search be carried out in the chain if the current check returns false). Although this may seem like a good solution, in most cases it will mean double access to the resource itself (once to check for existence, at another time to read it) and may be a performance problem in some scenarios, for example, “remote” template-based resources URLs are a potential performance issue, 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 we wanted, adapted to the specific needs of our application.

Thymeleaf + Spring integration packages offer the default implementation of IMessageResolver , which uses the standard Spring method to receive external messages using the MessageSource components declared in the Spring Application Context.

Standard Message Resolver

So, what does StandardMessageResolver look likeMessages requested by a specific template?

If the template name is “home” and it is in /WEB-INF/templates/home.html and the requested language is gl_ES, then this resolver 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 JavaDoc documentation for the StandardMessageResolver class for more information on how the full message search engine works.

Configuring a message finder

What should we do if we want to add a message conversion tool (or more) to a template engine? This is easy:

// Для настройки одного
templateEngine.setMessageResolver(messageResolver);
// Для настройки более одного
templateEngine.addMessageResolver(messageResolver);

And why do we want to have more than one message finder? For the same reason as the template finder: message organizers are ordered, and if the first cannot find a specific message, the second will be requested, then the third, etc.

15.3 Conversion Services


The transformation service, which allows us to perform data conversion and formatting operations using double-bracket syntax ($ {{...}}) , is actually an element of the standard dialect, not the Thymeleaf template engine itself.

Thus, the way to configure it is to configure the user 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 preconfigured with the implementation of IStandardConversionService , which integrates the native Spring conversion service infrastructure into Thymeleaf.

15.4 Logging


Thymeleaf pays great attention to event logging and always tries 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 written , depending on the level of detail that we want, and, in addition to general logging, it will use three special registrars associated with the TemplateEngine class, which we can configure separately for different purposes:

  • org.thymeleaf.TemplateEngine.CONFIG will display the detailed library configuration during initialization
  • org.thymeleaf.TemplateEngine.TIMER will display information about the time taken to process each template (useful for benchmarking!)
  • org.thymeleaf.TemplateEngine.cache is a prefix for a set of registrars that display specific cache information. Although cache logger names are user-configurable and therefore subject to change, by default they are:

    org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE
            org.thymeleaf.TemplateEngine.cache.EXPRESSION_CACHE

An example configuration for a Thymeleaf logging 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

Also popular now: