Working with Template Engines
1. Configuring Thymeleaf Template Engine
Example: Thymeleaf dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
| Property | Default |
|---|---|
spring.thymeleaf.prefix |
classpath:/templates/ |
spring.thymeleaf.suffix |
.html |
spring.thymeleaf.cache |
true (false in dev) |
spring.thymeleaf.mode |
HTML |
spring.thymeleaf.encoding |
UTF-8 |
2. Creating Thymeleaf Templates
Example: Basic Thymeleaf template
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="|Hello, ${name}!|">placeholder</h1>
</body>
</html>
3. Using Thymeleaf Expressions
| Syntax | Meaning |
|---|---|
${var} |
Variable expression |
*{field} |
Selection (within th:object) |
#{key} |
i18n message |
@{/path} |
URL (context-aware) |
~{fragment} |
Fragment ref |
|literal ${var}| |
Literal substitution |
4. Iterating Collections (th:each)
Example: Iterate list with row status
<tr th:each="user, stat : ${users}">
<td th:text="${stat.index}"></td>
<td th:text="${user.name}"></td>
<td th:classappend="${stat.odd} ? 'odd' : 'even'"></td>
</tr>
5. Conditional Rendering (th:if, th:unless)
| Attribute | Use |
|---|---|
th:if="${cond}" |
Render if true |
th:unless="${cond}" |
Render if false |
th:switch / th:case |
Switch statement |
th:remove="all/tag/body" |
Remove on render |
6. Including Fragments (th:fragment, th:replace, th:insert)
Example: Fragment include across templates
<!-- fragments/header.html -->
<header th:fragment="site-header(title)">
<h1 th:text="${title}"></h1>
</header>
<!-- page.html -->
<div th:replace="~{fragments/header :: site-header('Welcome')}"></div>
| Attribute | Behavior |
|---|---|
th:insert |
Insert fragment inside host tag |
th:replace |
Replace host tag with fragment |
th:include DEPRECATED |
Use insert/replace |
7. Handling Form Binding (th:object, th:field)
Example: Form binding with th:object and th:field
<form th:action="@{/users}" th:object="${form}" method="post">
<input type="text" th:field="*{name}" />
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span>
<button type="submit">Save</button>
</form>
8. Using FreeMarker as Alternative
| Property | Default |
|---|---|
spring.freemarker.template-loader-path |
classpath:/templates/ |
spring.freemarker.suffix |
.ftlh |
spring.freemarker.cache |
true |
Example: FreeMarker template syntax
<h1>Hello ${user.name}</h1>
<#list items as item>
<li>${item}</li>
</#list>
9. Using Mustache Templates
| Property | Default |
|---|---|
spring.mustache.prefix |
classpath:/templates/ |
spring.mustache.suffix |
.mustache |
spring.mustache.cache |
true |
10. Customizing Template Resolver Configuration
Example: Custom template resolver for email
@Bean
SpringResourceTemplateResolver emailResolver() {
SpringResourceTemplateResolver r = new SpringResourceTemplateResolver();
r.setPrefix("classpath:/email-templates/");
r.setSuffix(".html");
r.setTemplateMode(TemplateMode.HTML);
r.setOrder(1);
return r;
}