Thymeleaf如何实现非固定标签名动态渲染(如动态h1-h6标题)
Thymeleaf动态渲染非固定标签名实现方案
你当前使用的多标签+th:if判断的写法是最容易想到的实现,但冗余度高、后续维护成本大,Thymeleaf原生就支持更简洁的动态标签名渲染能力,完全可以替代重复的条件判断写法。
推荐方案:使用th:tag属性(Thymeleaf 3.0+ 原生支持)
Thymeleaf 3.0及以上版本的标准方言内置了th:tag属性,作用就是动态指定元素最终渲染出的DOM标签名,配合Thymeleaf的虚拟标签th:block(该标签自身不会被渲染到最终HTML中,只会输出其绑定的内容和指定标签),仅需少量代码就能实现h1-h6的动态输出:
<th:block th:tag="'h' + ${model.level}" th:text="${model.title}"> </th:block>
这个方案的优势非常明显:
- 无重复逻辑,代码量从原来的6行大幅缩减
- 后续如果需要给标题添加class、id、自定义属性或者事件绑定,仅需要在这一个标签上修改即可,不需要同步改6处
- 沿用
th:text渲染文本,会自动对内容做HTML转义,不存在XSS注入风险
建议对动态传入的level值做边界校验,避免传入非法值生成无效HTML标签,可以直接在模板内完成范围限制,示例:
<th:block th:tag="'h' + ${T(Math).max(1, T(Math).min(6, model.level))}" th:text="${model.title}"> </th:block>上述写法会自动将level值约束在1-6的区间内,哪怕传入超出范围的参数,最终也只会渲染合法的h1-h6标题标签。
低版本兼容方案
如果项目使用的是Thymeleaf 3.0以下的版本,没有th:tag能力,可以通过th:utext拼接HTML字符串实现,但必须严格处理内容安全:
<th:block th:utext="|<h${model.level}>${model.title}</h${model.level}>|" />
注意:
th:utext不会对输出内容做HTML转义,如果model.title是用户可提交的内容,必须提前在后端完成XSS转义,否则会存在注入风险,优先推荐升级Thymeleaf版本使用th:tag方案。
内容的提问来源于stack exchange,提问作者haui
相关产品推荐
相关产品推荐

