Is there a way to render a tag with a tag name that is not constant in the template? I want to produce a heading tag h1
, h2
, ..., or h6
depending on some attribute of the page model like in the following template:
<h1 th:text="${model.title}" th:if="${model.level == 1}"></h1>
<h2 th:text="${model.title}" th:if="${model.level == 2}"></h2>
<h3 th:text="${model.title}" th:if="${model.level == 3}"></h3>
<h4 th:text="${model.title}" th:if="${model.level == 4}"></h4>
<h5 th:text="${model.title}" th:if="${model.level == 5}"></h5>
<h6 th:text="${model.title}" th:if="${model.level == 6}"></h6>
Can this be done in a more clever way?
CodePudding user response:
Something like this would probably work but i doubt it be more readable and as such i would not recommend doing so. As debugging for a future dev might be more trouble than typing out all the ifs (or a switch) is.
<h1 id="placeholder">PLACEHOLDER<h1>
<script th:inline="javascript">
let element = /*[['h' ${model.level}]]*/ "";
let $header = $(document.createElement(element));
$("#placeholder").replaceWith($header);
</script>
Do keep in mind that this is just mock code, it might have some typos but the idea should be correct
CodePudding user response:
You can use th:utext
to output unescaped html. So something like this would work for example:
<th:block th:utext="|<h${model.level}>${model.title}</t${model.level}>|">
However, Thymeleaf wasn't really designed for this use case -- putting unescaped HTML into your templates is error prone and has security connotations (especially if you are taking in user input) and the template is hard to read now.
I would recommend just putting your original Thymeleaf into a fragment and using that.
HTML:
<th:block th:replace="index :: title(level=${model.level}, title=${model.title})" />
Fragment:
<th:block th:fragment="title(level, title)">
<h1 th:text="${title}" th:if="${level == 1}"></h1>
<h2 th:text="${title}" th:if="${level == 2}"></h2>
<h3 th:text="${title}" th:if="${level == 3}"></h3>
<h4 th:text="${title}" th:if="${level == 4}"></h4>
<h5 th:text="${title}" th:if="${level == 5}"></h5>
<h6 th:text="${title}" th:if="${level == 6}"></h6>
</th:block>