Thymeleaf templates
Thymeleaf is one of the template engines that has built-in support in Spring Boot. Read more about Thymeleaf syntax.
Add dependency to your project
dependencies {
...
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
}
Set default location for your templates in property file
# resource/application.properties
spring.thymeleaf.prefix=classpath:/templates
Suppose we have an article.html template in our templates directory. Then we can us it in controller
@GetMapping("/articles/{idArticle}")
fun showPage(@PathVariable idArticle: Long)
= ModelAndView("/article").apply {
// add objects, that will be passed to the template
addObject("articleModel", srv.loadData(idArticle))
}
If you run your Spring Boot application as a jar, you must add / before the template name.
multiple resolvers
You can add multiple resolvers for example for the different template locations. Thymeleaf has built-in resolvers, that can load external templates:
- ClassLoaderTemplateResolver - resolves templates inside classpath
- FileTemplateResolver - resolves template on file system
- ServletContextTemplateResolver - can be used inside your servlet
- UrlTemplateResource - resolves template from url;
- SpringResourceTemplateResolver - resolves templates using Spring's Resource Resolution mechanism
@Configuration
class ThymeleafCfg {
@Bean
fun fileTemplateResolver() = FileTemplateResolver().apply {
prefix = "./resources/tpl"
suffix = ".html"
// set patterns for the template name
// resolvablePatterns = setOf("tpl-*")
templateMode = TemplateMode.HTML
characterEncoding = "UTF-8"
order = 1 // order should start with 1
// allows to pass control to the next resolver in chain
checkExistence = true
name = "file-resolver" // optionally
cacheTTLMs = 30 * 60 * 1000 // cache template 30 min
// Set to false if you want templates to
// be automatically updated when modified.
// set to false, if you want reload
isCacheable = false // default true
}
// this is same as we set in property file
// spring.thymeleaf.prefix=classpath:/templates
@Bean
fun defaultTemplateResolver() = ClassLoaderTemplateResolver().apply {
prefix = "/templates" // classpath: will be prepend
suffix = ".html"
templateMode = TemplateMode.HTML
characterEncoding = "UTF-8"
order = 2 // Order should start with 1
checkExistence = false
}
}
custom resolvers
You can define own resolver by implementing the ITemplateResolver interface or extend existing.
For example you can extend StringTemplateResolver class to create resolver that load template from database.
// Entity for template
@Document
class PageTemplate {
@Id
var name: String = ""
var content: String=""
}
// Resolver that loads Thymeleaf template from mongoDB.
// You can adapt it for any db.
@Component
class DbTemplateResolver : StringTemplateResolver() {
@Autowired
lateinit var pageTemplateRepo: PageTemplateRepository
init {
// setup your default configuration
isCacheable = false
}
// try load template by name
// if found then call super method and pass content of template
// if not found then return null
override fun computeTemplateResource(
configuration: IEngineConfiguration?,
ownerTemplate: String?,
template: String?, // template name
templateResolutionAttributes: MutableMap<String, Any>?
): ITemplateResource? = pageTemplateRepo
.findByIdOrNull(
if ((template ?: "default-template").trim().isEmpty()) {
"default-template"
} else template!!
)
?.let { pageTemplate ->
super.computeTemplateResource(
configuration, ownerTemplate,
pageTemplate.content, templateResolutionAttributes
)
}
}