Как перейти от th:include в Thymeleaf 3.1?

Вопрос или проблема

На thymeleaf-3.1 th:include устарел (
https://github.com/thymeleaf/thymeleaf/issues/913), поэтому я пытаюсь перенести свои включения, но без успеха.

Моя цель — создать фрагмент, который определяет элемент таблицы th с набором данных.
Сейчас только для одного единственного элемента th в таблице я хочу применить другой css style (в этом примере: text-align:right).
Вот что у меня было раньше:

home.html:

<table>
 <thead>
  <tr>
    <th scope="col" th:include="~{components/tableheader :: tableheader('test')}" 
        style="text-align:right"/>
  </tr>
 </thead>
</table>

components/tableheader.html:

<html xmlns="http://www.w3.org/1999/html" xmlns:th="http://www.thymeleaf.org">
        <th scope="col" th:fragment="tableheader(text)">
            <div th:text="${text}"/>
            <!-- другие элементы -->
        </th>
</html>
<table>
 <thead>
  <tr>
    <th scope="col" style="text-align:right">
        <div>test</div>
    </th>
  </tr>
 </thead>
</table>

НО: th:include устарел в последней версии thymeleaf, и рекомендуют использовать th:insert.

Проблема: th:insert теряет дополнительные стили и плюс вставляет “призрачную” строку, которая затем отображается как:

<table>
 <thead>
  <tr>
    <th scope="col" style="text-align:right"></th>  <!-- вот в чем проблема -->
    <th scope="col">
        <div>test</div>
    </th>
  </tr>
 </thead>
</table>

Так что вы видите, я не могу просто заменить th:include. Как это можно исправить?

Ответ или решение

Для успешной миграции с th:include на th:insert в Thymeleaf 3.1, необходимо учитывать несколько важных моментов и придерживаться структуры, которая обеспечит корректное отображение ваших компонентов. Рассмотрим, как решить данную задачу на основе примера, который вы привели.

Проблема

Действительно, th:include устарел, и в данном случае, его замена на th:insert приводит к созданию лишнего элемента (<th>...</th>) в результате вставки фрагмента и потере дополнительных стилей. Мы можем обойти эту проблему, изменяя способ определения ваших фрагментов и использования th:insert.

Решение

  1. Изменение Angular фрагмента: Вам потребуется сделать изменения в вашем фрагменте components/tableheader.html, чтобы он корректно воспринимал атрибуты стилей от родительского элемента.

  2. Передача стилей через атрибуты: Один из способов решения проблемы заключается в передаче стиля через атрибут. Для этого можно использовать th:attr, чтобы передать необходимые атрибуты в фрагмент.

Исправленная версия

Файл home.html:

<table>
 <thead>
  <tr>
    <th scope="col" th:insert="~{components/tableheader :: tableheader('test')}"
        th:attr="style='text-align:right'"/>
  </tr>
 </thead>
</table>

Файл components/tableheader.html:

<html xmlns="http://www.w3.org/1999/html" xmlns:th="http://www.thymeleaf.org">
    <th scope="col" th:fragment="tableheader(text)" th:attr="style=${style}">
        <div th:text="${text}"></div>
        <!-- другие элементы -->
    </th>
</html>

Объяснение

  1. Использование th:attr: В home.html, мы использовали th:attr для установки стиля непосредственно на элемент <th>, который будет передан в фрагмент. Это предотвращает создание пустого элемента в результате применения th:insert.

  2. Передача параметров: th:insert теперь вызывает ваш фрагмент tableheader и передает нужные параметры, включая возможные стили через th:attr. В components/tableheader.html, добавлен параметр th:attr="style=${style}", который получает стиль и применяет его к элементу <th>.

Результат

После выполнения вышеописанных шагов, ваше окончательное HTML представление будет выглядеть корректно:

<table>
 <thead>
  <tr>
    <th scope="col" style="text-align:right">
        <div>test</div>
    </th>
  </tr>
 </thead>
</table>

Заключение

С использованием этого подхода вы сможете избежать проблем, связанных с устаревшими атрибутами th:include, и выполните их замену на th:insert без потерь стилей и лишних элементов. Этот метод улучшит читаемость кода и облегчит его поддержку в будущем.

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

Капча загружается...