When building HTML templates wiht Thymeleaf template engine, you may end up with a situation where an HTML element needs to have text coming from localization resources, but also it needs to have some additonal child elements which can't be replaced during template rendering. One of the examples could be Bootstrap and its page header

<div class="page-header">
  <h1>Example page header <span class="glyphicon glyphicon-search"></span></h1>
</div>

Which looks like that:

Thymeleaf Bootstrap page header

In Thymeleaf very obvious approach would be to use following template:

<div class="page-header">
  <h1 th:text="#{home.welcom}">
    Example page header 
    <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

Assuming that your localization file contains home.welcom=Welcome message entry, your generated HTML would look like:

<div class="page-header">
  <h1>Welcome message</h1>
</div>

That is obviously wrong as it deleted our icon tag (<span class="glyphicon glyphicon-search"></span>). So how to fix it? There are some alternative solutions to have it working as expected.

Solution 1

The first solution would be to put <span class="glyphicon glyphicon-search"></span> into localization file e.g.

home.welcom=Welcome message <span class="glyphicon glyphicon-search"></span>

With this approach we would need to change th:text="#{home.welcom}" into th:utext="#{home.welcom}" to get content of home.welcome localization message in unescaped format.

So following template:

<div class="page-header">
  <h1 th:utext="#{home.welcom}">
    Example page header
    <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

Would give something like:

<div class="page-header">
  <h1>
    Welcome message <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

Using th:text attribute, we would get somethig like:

<div class="page-header">
  <h1 th:utext="#{home.welcom}">
    Welcome message &lt;span class=&quot;glyphicon glyphicon-search&quot;&gt;&lt;/span&gt;
  </h1>
</div>

Solution 2

We can insert additional child element to h1 to hold a welcome message e.g.

<div class="page-header">
  <h1>
    <span th:text="#{home.welcom}">Example page header</span>
    <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

That would give us something like:

<div class="page-header">
  <h1>
    <span>Welcome message</span>
    <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

And if we really want to get rid of the first span element, we can use th:remote="tag" Thymeleaf attribute e.g.

<div class="page-header">
  <h1>
    <span th:text="#{home.welcom}" th:remove="tag">Example page header</span>
    <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

That will result in the output as follows:

<div class="page-header">
  <h1>
    Welcome message
    <span class="glyphicon glyphicon-search"></span>
  </h1>
</div>

Enjoy!