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:
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
Multiple resolvers
@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.
Ccustom resolver
// 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
)
}
}