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;
}