Thymeleaf Expressions in Spring Boot
Thymeleaf let us create dynamic views via extensive use of expressions in the template files. The simple form of expressions fall into four main categories.
Variable expressions
Variable expressions are the most commonly used ones in thymeleaf templates. These expressions help bind the data from the template context(model) into the resulting html(view). For example, The following snippet places the value of userInfo.getFirstName() as the text in side the div. Similarly, the active flag decides whether the checkbox is checked or not.
<div th:text="${userInfo.firstName}"></div>
<input type="checkbox" name="active" th:checked="${userInfo.active}"/>
Code language: HTML, XML (xml)
Here, the expression ${userInfo.firstName}
is an OGNL expression that is equivalent to
((UserInfo)context.getVariable("userInfo")).getFirstName()
Code language: CSS (css)
Thymeleaf Selection expressions
The selection expression let you select a specific child attribute from the current thymeleaf context. To use these expressions you first need to define a th:object
attribute. After that, You can use the selection expressions to extrapolate the appropriate fields.
Let’s say, we have userInfo
object that contains firstName
and lastName
. So instead of doing ${userInfo.firstName}
every time, you can do something like this.
<div th:object="userInfo">
<div th:text="*{firstName}"></div>
<div th:text="*{lastName}"></div>
</div>
Code language: HTML, XML (xml)
The above snippet is equivalent to the following.
<div>
<div th:text="${userInfo.firstName}"></div>
<div th:text="${userInfo.lastName}"></div>
</div>
Code language: HTML, XML (xml)
The selection expressions are best when used together with form elements. As form-inputs are mapped to a @ModelAttribute
, it’s easier to bind them without having to worry about managing each input elements individually. Here is an example for that.
<form method="post" th:action="@{/}" th:object="${userInfo}">
<input type="text" th:field="*{firstName}"/>
<input type="text" th:field="*{lastName}"/>
<input type="submit" value="Create User">
</form>
Code language: HTML, XML (xml)
If you want to learn more about form-handling, take a look at Thymeleaf Form Handling in Spring Boot.
Message expressions in Thymeleaf Views
Message expressions let you externalize common texts into a properties file. These values then can be referred in template as #{message.property.key}
. Let’s say you have a welcome message that you want to show on every view. However, hardcoding this message on all of these views is a bad idea. So let’s create a messages.properties
.
welcome.text=Greetings fellow user..!
Thymeleaf will look for this file ( place it under src/main/resources/
) in class path and resolve their values. Here is a simple example for this expression.
<h1 th:text="#{welcome.text}">Hello user!</h1>
Code language: HTML, XML (xml)
Another good thing about the message expression is that they can have placeholders. So the following is also possible.
welcome.text=Greetings {0}..!
With this properties set up the followings are possible.
messages with static placeholders
A simple string literal can be passed to fill the placeholders. Even though this is possible, there is no practical use for this implementation.
<h1 th:text="#{welcome.text('User')}">Hello user!</h1>
Code language: HTML, XML (xml)
messages with dynamic placeholders
The ideal case with messages containing placeholder would be to use a variable expression. For example, the below set up would welcome the user by their current name.
<h1 th:text="#{welcome.text(${userInfo.firstName})}">Hello user!</h1>
Code language: HTML, XML (xml)
A single message.properties entry can contain more than one placeholder. In such cases, the parameters can be a comma separated list just like a method call.
Link Expressions for Controller Lookup
For a html view, URLs are very important. For this reason, thymeleaf provides URL expressions to evaluate them to controller paths using the @{expression}
format. In thymeleaf templates, a URL can be one of the following.
- Absolute URLs that are fully qualified URLs. For example,
https://springhow.com/tags/thymeleaf/
- Relative URLs that are,
- Relative to the current page. For example
manage/edit
- Relative to context path. For example,
/users/manage/edit
If the server has a context path(server.servlet.context-path
), it will be appended to the value. - Relative to the server root. For example
~/some/path/
This case is for when the application is hosted along with other applications in a same domain or IP. - Finally, Protocol relative. For example
//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css
. This one is similar to the absolute URL except the URL will have thehttp
orhttps
scheme for protocol based on the server’s protocol.
- Relative to the current page. For example
The following example represents each of these url implementations.
<a th:href="@{https://springhow.com/tags/thymeleaf/}">SpringHowSite</a>
<a th:href="@{//springhow.com/tags/thymeleaf/}">SpringHowSite But relative to server protocol</a>
<a th:href="@{manage/edit}">Edit Page</a>
<a th:href="@{/users/manage/edit}">Another way to Edit page</a>
<a th:href="@{~/corporate/contact-us/}">Contact us</a>
Code language: HTML, XML (xml)
At some point these urls may contain path variables. In these cases, you can use placeholders to evaluate them just like mvc controllers as shown below.
<a th:href="@{/users/{userId}/edit(userId=${userInfo.id})}">View user by Id</a>
Code language: HTML, XML (xml)
Here {userId}
is the placeholder. You fill this placeholder via expressions using (userId=${userInfo.id})
. If your url contains multiple placeholders you can use comma separated mapping. For example let’s say currentOperation
takes the values between ‘View’,‘Update’ and ‘Delete’. This way we can further customize the above link as shown below.
<a th:href="@{/users/{userId}/{operation(userId=${userInfo.id},operation=${currentOperation})}"
th:text="${currentOperation + ' user by Id'">
</a>
Code language: HTML, XML (xml)
Conclusion
To conclude, These are the important categories of thymeleaf expressions in Spring Boot. You can learn more about thymeleaf and Spring Boot from the following posts.