Что такое Thymeleaf и зачем он нужен?
Thymeleaf — это современный серверный шаблонизатор для Java-приложений, предназначенный для генерации HTML, XML, JavaScript, CSS и текстовых файлов. В отличие от JSP (JavaServer Pages), Thymeleaf предлагает более чистый, читаемый и естественный синтаксис, который легко понимать как разработчикам, так и дизайнерам.
Основное преимущество Thymeleaf заключается в том, что его шаблоны являются корректными HTML-документами. Это означает, что вы можете открыть шаблон в браузере без запуска сервера и увидеть его структуру. Динамические данные подставляются с помощью специальных атрибутов, начинающихся с префикса th:.
Thymeleaf идеально интегрируется со Spring Framework (особенно Spring Boot), но может использоваться и как самостоятельная библиотека. Он поддерживает макеты (layouts), фрагменты (fragments), условные конструкции, циклы, работу с формами, интернационализацию (i18n) и многое другое.
Установка Thymeleaf
Так как Thymeleaf — это Java-библиотека, она устанавливается через системы управления зависимостями Maven или Gradle. Аналога pip install для Java не существует.
Установка через Maven (pom.xml)
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
Установка через Gradle (build.gradle)
implementation 'org.thymeleaf:thymeleaf:3.1.2.RELEASE'
Для Spring Boot (рекомендуется)
Если вы используете Spring Boot, достаточно добавить стартер:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Spring Boot автоматически сконфигурирует Thymeleaf с разумными настройками по умолчанию.
Быстрый старт с примером кода
Создадим простое консольное приложение, которое использует Thymeleaf для генерации HTML.
Шаг 1: Создайте шаблон (src/main/resources/templates/hello.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello Thymeleaf</title>
</head>
<body>
<h1 th:text="${message}">Default Message</h1>
<p>Current date: <span th:text="${#dates.format(#dates.createNow(), 'dd-MM-yyyy')}">01-01-2024</span></p>
</body>
</html>
Шаг 2: Напишите Java-код для обработки шаблона
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
public class ThymeleafQuickStart {
public static void main(String[] args) {
// 1. Настройка резолвера шаблонов
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix("/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML");
// 2. Создание движка шаблонов
TemplateEngine engine = new TemplateEngine();
engine.setTemplateResolver(resolver);
// 3. Создание контекста с данными
Context context = new Context();
context.setVariable("message", "Привет, Thymeleaf!");
// 4. Обработка шаблона
String result = engine.process("hello", context);
System.out.println(result);
}
}
Результат выполнения:
<!DOCTYPE html>
<html>
<head>
<title>Hello Thymeleaf</title>
</head>
<body>
<h1>Привет, Thymeleaf!</h1>
<p>Current date: <span>15-03-2024</span></p>
</body>
</html>
Основные методы и функции Thymeleaf
1. th:text — вывод текста
Что делает: Заменяет содержимое HTML-элемента на указанное значение с автоматическим экранированием HTML-символов.
Параметры: Выражение (обычно переменная из контекста)
Пример:
<p th:text="${user.name}">Имя пользователя</p>
<p th:text="'Привет, ' + ${user.name} + '!'">Привет, мир!</p>
2. th:utext — неэкранированный вывод HTML
Что делает: Выводит HTML-код без экранирования. Используйте с осторожностью, чтобы избежать XSS-атак.
Параметры: Выражение
Пример:
<div th:utext="${htmlContent}">
<strong>Жирный текст</strong>
</div>
3. th:each — цикл по коллекции
Что делает: Итерирует по коллекции, массиву или итератору, повторяя HTML-элемент для каждого элемента.
Параметры: item : ${collection}, где item — переменная для текущего элемента
Пример:
<ul>
<li th:each="product : ${products}" th:text="${product.name}">Название товара</li>
</ul>
<!-- С индексом -->
<ul>
<li th:each="product, stat : ${products}">
<span th:text="${stat.count} + '. ' + ${product.name}">1. Товар</span>
</li>
</ul>
4. th:if и th:unless — условные конструкции
Что делает: th:if отображает элемент, если условие истинно. th:unless — если ложно.
Параметры: Булево выражение
Пример:
<div th:if="${user.isAdmin}">
<p>Панель администратора</p>
</div>
<div th:unless="${user.isBlocked}">
<p>Пользователь активен</p>
</div>
5. th:switch и th:case — множественное ветвление
Что делает: Реализует конструкцию switch-case для выбора одного из нескольких вариантов.
Параметры: Выражение для сравнения
Пример:
<div th:switch="${user.role}">
<p th:case="'ADMIN'">Администратор</p>
<p th:case="'USER'">Пользователь</p>
<p th:case="'GUEST'">Гость</p>
<p th:case="*">Неизвестная роль</p>
</div>
6. th:href и th:src — динамические ссылки
Что делает: Генерирует URL для атрибутов href (ссылки) и src (изображения/скрипты).
Параметры: URL-выражение с @{...}
Пример:
<a th:href="@{/products/{id}(id=${product.id})}">Подробнее</a>
<img th:src="@{/images/{name}(name=${product.image})}" alt="Изображение" />
7. th:object и *{...} — работа с объектами
Что делает: Устанавливает объект для выборки, позволяя использовать сокращенный синтаксис *{...} для обращения к его полям.
Параметры: Объект
Пример:
<div th:object="${user}">
<p>Имя: <span th:text="*{name}">Иван</span></p>
<p>Email: <span th:text="*{email}">ivan@example.com</span></p>
</div>
8. th:field — работа с формами
Что делает: Привязывает поля формы к объекту модели. Автоматически устанавливает id, name, value и обрабатывает ошибки валидации.
Параметры: Выражение *{...} для поля объекта
Пример:
<form th:action="@{/users/save}" th:object="${user}" method="post">
<input type="text" th:field="*{name}" placeholder="Имя" />
<input type="email" th:field="*{email}" placeholder="Email" />
<button type="submit">Сохранить</button>
</form>
9. th:replace и th:insert — включение фрагментов
Что делает: Включают другие шаблоны или фрагменты. th:replace заменяет текущий элемент, th:insert вставляет внутрь.
Параметры: Имя шаблона и селектор фрагмента
Пример:
<!-- Фрагмент в header.html -->
<div th:fragment="header">
<h1>Мой сайт</h1>
</div>
<!-- Включение в другой шаблон -->
<div th:replace="fragments/header :: header"></div>
10. #dates, #strings, #lists — утилитарные объекты
Что делает: Предоставляют готовые функции для работы с датами, строками и коллекциями.
Параметры: Зависят от конкретной функции
Пример:
<!-- Работа с датами -->
<p th:text="${#dates.format(#dates.createNow(), 'dd.MM.yyyy HH:mm')}">15.03.2024 14:30</p>
<!-- Работа со строками -->
<p th:text="${#strings.toUpperCase(user.name)}">ИВАН</p>
<p th:text="${#strings.substring(user.email, 0, 5)}">ivan@</p>
<!-- Работа со списками -->
<p th:text="${#lists.size(products)}">10</p>
<p th:text="${#lists.contains(products, 'Молоко')}">true</p>
Реальный практический пример использования
Создадим полноценное веб-приложение для интернет-магазина со списком товаров, корзиной и формой заказа.
Шаг 1: Модель данных (Product.java)
public class Product {
private Long id;
private String name;
private double price;
private String category;
private boolean inStock;
// Конструкторы, геттеры, сеттеры
public Product(Long id, String name, double price, String category Также в библиотеке
Мониторинг приложений TypeScript с Appmetrics
Авторизация и аутентификация в JavaScript (Node.js): полное руководство
OAuth клиент для JavaScript (Node.js): обзор и примеры использования
Работа с XML в Swift: парсинг, создание и обработка данных (iOS/macOS)