Since Thymeleaf 3, Thymeleaf prefers the use of SpringResourceTemplateResolver
(https://www.thymeleaf.org/doc/articles/thymeleaf3migration.html). So I decided to go from ClassLoaderTemplateResolver
to SpringResourceTemplateResolver
:
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
registry.setOrder(1);
}
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding("UTF-8");
resolver.setOrder(0);
resolver.setCheckExistence(true);
return resolver;
}
@Bean
public SpringResourceTemplateResolver templateResolver2() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("/templates-2/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding("UTF-8");
resolver.setOrder(1);
resolver.setCheckExistence(true);
return resolver;
}
}
Unfortunately, when implementig like this, I'll get an error:
Error resolving template [index], template might not exist or might not be accessible by any of the configured Template Resolvers
.
To be honest, I've simple replaced ClassLoaderTemplateResolver
with SpringResourceTemplateResolver
in the hope, this will work. It doesn't. But searching for a working solution dealing with two template locations, all I find are outdated samples using ClassLoaderTemplateResolvers.
Trying to implement the code snippet provided by Thymeleaf as shown here https://www.thymeleaf.org/doc/articles/thymeleaf3migration.html won't work either when using two template directories, besides the fact, that this code itself uses the deprecated WebMvcConfigurerAdapter.
Is there any example how to configure a Spring Boot application using Thymeleaf having two or more template locations which isn't completely outdated?
CodePudding user response:
So after a while and many many tryouts I've finally got the templates working. Since there isn't any decent answer to my question flying round the internet, I will post my solution for others:
@Configuration
public class ThymeleafConfig implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(@Autowired ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("classpath:/templates-1/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(1);
templateResolver.setCheckExistence(true); /* FYI: necessary to chain TemplateResolvers */
templateResolver.setCacheable(false); /* FYI: during development -> false, so that we can see changes we make */
return templateResolver;
}
@Bean
public SpringResourceTemplateResolver templateResolver2() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("classpath:/templates-2/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(2);
templateResolver.setCheckExistence(true); /* FYI: necessary to chain TemplateResolvers */
templateResolver.setCacheable(false); /* FYI: during development -> false, so that we can see changes we make */
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
/* SpringTemplateEngine automatically applies SpringStandardDialect and
enables Spring's own MessageSource message resolution mechanisms. */
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(this.templateResolver());
templateEngine.addTemplateResolver(this.templateResolver2());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(this.templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setCache(false); /* FYI: during development -> false */
viewResolver.setOrder(1);
return viewResolver;
}
}
I hope this will help others to save time and nerves^^.
CodePudding user response:
If you are using Spring Boot, you can add an extra resolver on top of the default one like this:
First, add this to application.properties
:
# This ensures that the default HTML template resolver of Thymeleaf has priority over our custom SVG resolver
spring.thymeleaf.template-resolver-order=0
Then add the extra resolver in a @Configuration
class:
@Configuration
public class MyApplicationConfiguration {
@Bean
public ITemplateResolver svgTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("classpath:/templates/svg/");
resolver.setSuffix(".svg");
resolver.setTemplateMode("XML");
return resolver;
}
}
There is no need to manually define SpringTemplateEngine
and ViewResolver
beans.
You can disable caching during development using spring.thymeleaf.cache=false
.