Хабрахабр

Thymeleaf: диалект Layout + Spring Boot 2

Диалект Layout — это диалект Thymeleaf, который позволяет пользователям создавать макеты и шаблоны для повторного использования HTML кода. Он имеет иерархический подход и использует шаблон декоратора для «декорирования» файлов макета. Layout Dialect является отдельным проектом и не поставляется с Thymeleaf. Тем не менее, это открытый исходный код, доступный на GitHub, он хорошо документирован и, как кажется, также поддерживается в хорошем состоянии.

Установка

Нам нужно будет добавить стартовый пакет Thymeleaf к вашему Spring Boot pom:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

Однако, начиная с Spring Boot 2, этого уже недостаточно. Pom диалекта не является частью Spring Boot, и мы должны добавить его самостоятельно:

<dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> <version>2.3.0</version> </dependency>

В примерах кода также используется Bootstrap, поэтому необходимо также добавить веб-файлы:

<dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.0.0</version> </dependency>

В качестве последнего шага нам нужно создать bean-компонент LayoutDialect в аннотированном классе @Configuration.

@Bean public LayoutDialect layoutDialect()

Пошли далее.

Layout Dialect пример

Этот пример покажет, как мы можем использовать Layout Dialect, чтобы определить макеты для наших страниц, чтобы мы могли лучше использовать код повторно: с помощью страницы index.html, которая использует layout.html в качестве макета. Имя Layout.html — произвольное и может быть любым. Там добавлено еще несколько файлов, но они только для демонстрации.

Spring Boot автоматически найдет все шаблоны Thymeleaf в каталоге resources/templates. На картинке структура папки ресурсов.

Layout.html

<!DOCTYPE html> <html> <head> <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Igorski.co</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.min.css}" rel="stylesheet" media="screen" /> </head> <body> <div th:replace="fragments/header :: header"> This header content is going to be replaced.</div> <div class="container"> <div class="row"> <div class="col-2" layout:fragment="sidebar"> <h1>This is the layout's sidebar</h1> <p>This content will be replaced if the page using the layout also defines a layout:fragment="sidebar" segment.</p> </div> <div class="col" layout:fragment="content"> <h1>This is the Layout's main section</h1> <p>This content will be replaced if the page using the layout also defines a layout:fragment="content" segment. </p> </div> </div> </div> <footer th:insert="fragments/footer :: footer" class="footer"> This content will remain, but other content will be inserted after it. </footer> </body> </html>

В layout.html используются два из пяти процессоров, представленных в Layout Dialect. Во-первых, это макет: процессор шаблонов заголовков. Процессор шаблона заголовка помогает пользователю определить лучший заголовок для получающейся страницы. В этом примере он определяет окончательный заголовок как комбинацию заголовка страницы и заголовка макета. Для этого используются два специальных токена, представленных в Layout Dialect, $LAYOUT_TITLE и $CONTENT_TITLE.

Этот процессор позволяет нам определять заполнители контента в наших макетах. Наибольшее значение в layout.html имеют два заполнителя (или фрагмента), определенных макетом: процессор фрагмента. В примере определены два разных фрагмента, один для боковой панели, а другой для основного контента. Содержимое этих заполнителей будет позже заменено содержимым страниц, использующих макет. Мы, однако, можем иметь столько фрагментов, сколько пожелаем, при условии, что все они имеют разные имена.

Index.html

<!DOCTYPE html> <html xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="~{layouts/layout}"> <head> <title>Home Page</title> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link th:href="@{/css/core.css}" rel="stylesheet" media="screen" /> </head> <body> <div class="container"> <div class="row"> <div class="col-2" layout:fragment="sidebar"> <h1>Sidebar</h1> <a href="#">Login</a> </div> <div class="col" layout:fragment="content"> <h1>Welcome to the Index page</h1> <br>This content is replacing the content of the layout:fragment="content"<br> placeholder in layout.html</p> </div> </div> </div> </body> </html>

Мы заявляем, что index.html использует layout.html в качестве своего макета с процессором layout: decorate. Сделав это, мы объявляем, что index.html будет использовать шаблон layout.html. Здесь самое главное — использование процессора фрагментов. Он указывает содержимое, которое будет использоваться вместо содержимого фрагментов макета с тем же именем. Еще одна вещь, которую стоит упомянуть, это заголовок. На полученной странице index.html, которую мы получим, после обработки заголовок будет представлять собой комбинацию двух заголовков, один из index.html, а другой из макета. Они будут объединены.

Но после обработки мы видим, что index.html сильно отличается. Как layout.html, так и index.html можно просматривать в браузере без какой-либо обработки. Содержимое index.html используется для оформления макета и размещения содержимого внутри макета на основе того, что определяет макет.

Однако они используют процессоры Thymeleaf Standard Layout th:replace и th:insert. В примере присутствуют два других элемента: верхний и нижний колонтитулы. Они более или менее делают то же самое. Очень похожи на последние два из пяти процессоров, представленных в Layout Dialect, layout:insert и layout:replace. Это больше характерно для типовой формы Thymeleaf. В отличие от предыдущих процессоров, которые мы обсуждали, эти два используют не иерархический, а включающий подход.

Он имеет как верхний, так и нижний колонтитулы, хотя ни один из них не упоминается в разметке index.html. На картинке окончательный вид страницы.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»