Java Spring Thymeleaf `th:each` внутри тега `<style>`

Активные языки моего веб-приложения хранятся в Java List, и этот список доступен Thymeleaf.
Снаружи тега <style> это просто и работает как шарм:

<button th:each = "lang : ${ activeLanguages }" th:data-lang = "${ lang.languageTag }" onclick = "setLang( this );">
    <span th:text = "${ lang.localName }"></span>
</button>

Можно ли выпустить тег th:each внутри <style>, чтобы избежать жесткого кодирования активных языков в классах CSS?

Вот как у меня пока:

<style>
    .Flag.IE { background-image:url("/IE.svg"); }
    .Flag.HR { background-image:url("/HR.svg"); }
    .Flag.EN { background-image:url("/EN.svg"); }
</style>

Это то, что я хочу (хорошо, не совсем это, а решение таким образом):

<style>
---> th:each = "lang : ${ activeLanguages }" <---
    .Flag.${ lang.iso2Country.toUpperCase() } {
        background-image:url("/${ lang.iso2Country.toUpperCase() }.svg");
    }
---> th:each END <---
</style>

Обновлено: у меня есть рабочее решение, но оно очень уродливое:

<style th:each = "lang : ${ webData.activeLanguages }">
    .Flag.[[ ${ lang.iso2Country.toUpperCase() } ]]::before {
        background-image:url("/[[ ${ lang.iso2Country.toUpperCase()} ]]");
    }
</style>
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Считаете ли вы это менее уродливым или нет, это, вероятно, субъективно...

Вы можете использовать CSS-инлайнинг, объявив тег стиля следующим образом:

<style th:inline = "css">
   ...
</style>

А затем вы можете объединить это с текстовой встроенной итерацией, аналогично тому, что показано в этом разделе документации:

<style th:inline = "css">
    [# th:each = "lang : ${activeLanguages}"]
        [#th:block th:utext = "|.Flag.${lang.languageTag} \{|" /]
        [#th:block th:utext = "|background-image: url('${lang.languageTag}.svg');|" /]
        [#th:block th:utext = "|}|" /]
    [/]
</style>

Это создает HTML, подобный следующему:

<style>            
    .Flag.XY {
        background-image: url('XY.svg');
    }
    .Flag.AB {
        background-image: url('AB.svg');
    }        
</style>

ВНИМАНИЕ! для этого необходимо использовать th:utext, что несет в себе угрозу безопасности, если оно обрабатывает НЕДОВЕРЕННЫЕ данные, предоставленные пользователем. Но если у вас есть собственный заранее определенный список языков (пользователи не могут «предоставить» эти значения, они могут выбрать только один из них), тогда текст, используемый для переменных Thymeleaf, должен быть безопасным. Но убедиться в том, что это так, зависит от вас.


ОБНОВЛЕНИЕ - более лаконично и безопаснее

Есть более краткий способ сделать это:

<style th:inline = "css">
    [# th:each = "lang : ${activeLanguages}"]
        .Flag.[[${lang.languageTag}]] {
            background-image: url("/[[${lang.languageTag}]].svg");
        }
    [/]
</style>

Здесь встроенный текст на самом деле представляет собой обычный текст, а переменные Thymeleaf вставляются между [[ и ]].

Результаты:

<style>
    .Flag.XY {
        background-image: url("/XY.svg");
    }
    .Flag.AB {
        background-image: url("/AB.svg");
    }
</style>

Что еще хорошо в этом, так это то, что мы можем использовать [[...]] вместо [(...)] — это означает, что любой потенциально опасный контент в ${...} будет безопасно экранирован рендерером Thymeleaf.

Так что мое предыдущее предупреждение не относится к этому подходу.

О да, это то, что я хотел получить! Я использовал термин «уродливый», потому что мое решение создает отдельный блок стилей для каждого языка вместо того, чтобы создавать один блок стилей и помещать в него все языки.

horvoje 20.06.2024 18:27

Другие вопросы по теме