Conditionals in a Template

In addition to iteration, Thymeleaf can also add or remove content on a webpage based on certain conditions. Going back to the coffee example, we could generate the ordered list ONLY IF coffeeOptions contains data. If the ArrayList is empty, then there is no need to include the <ol> element. Instead, the template could include a <p> element with text stating that there are no options to select.

Just like the for/each syntax differs between Java and Thymeleaf, we need to examine how to include conditionals in our templates. The logic remains the same, but the implementation requires practice.

Display Content if

The general syntax for including a conditional in Thymeleaf is:

th:if = "${condition}"
  1. The th:if statement gets placed inside an HTML tag.
  2. condition represents a boolean variable provided by the controller.
  3. Alternatively, condition can be a statement that evaluates to true or false.

If condition evaluates to true, then Thymeleaf adds the HTML element to the webpage, and the content gets displayed in the view. If condition is false, then Thymeleaf does NOT generate the element, and the content stays off the page.

Example

Assume that coffeeOptions and userSelection represent an ArrayList and String, respectively, that are passed in by the controller.

<ol th:if = "${coffeeOptions.size() > 1}">
    <li th:each="item : ${coffeeOptions}" th:text="${item}"></li>
</ol>

<h2 th:if = '${userSelection.equals("instant")}'>You can do better!</h2>

The conditional in line 1 checks that coffeeOptions contains more than one item. If true, then the ordered list is rendered in the view. The th:if statement in line 5 compares a user’s flavor choice to the string "instant". If they match, then Thymeleaf adds the heading element to the view.

Adding vs. Displaying/Hiding

th:if determines if content is added or not added to a page. This is different from deciding if content should be displayed or hidden.

Hidden content still occupies space on a page and requires some amount of memory. When th:if evaluates to false, content remains absent from the page—requiring neither space on the page nor memory. This is an important consideration when including items like images or videos on your website.

What is true?

The th:if = "${condition}" attribute can evaluate more than simple boolean variables and statements. It will also return true according to these rules:

  1. If condition is a boolean or statement and true.
  2. If condition is a non-zero number or character.
  3. If condition is a string that is NOT "false", "off", or "no".
  4. If condition is a data type other than a boolean, number, character, or String.

th:if will evaluate to false whenever condition is null.

unless Instead of else

In Java, we use an if/else structure to have our code execute certain steps when a variable or statement evaluates to true but a different set of steps for a false result. Thymeleaf provides a similar option with th:unless:

th:unless = "${condition}"

Just like th:if, the th:unless attribute gets placed inside an HTML tag. In this case, however, Thymeleaf adds the HTML element to the webpage when condition evaluates to false.

We could update our coffee code with an unless:

Note
<h2 th:unless = '${userSelection.equals("instant")}'>Excellent choice!</h2>

As long as userSelection is NOT "instant", the condition evaluates to false, and the h2 element gets added to the view.

If we want to set up a situation like if true, do this thing. Otherwise, do this other thing, we need to pair a th:if with a th:unless.

Example
<ol th:if = "${coffeeOptions.size()}">
    <li th:each="item : ${coffeeOptions}" th:text="${item}"></li>
</ol>

<p th:unless = "${coffeeOptions.size()}">No coffee brewed!</p>

If coffeeOptions.size() evaluates to 0, then Thymeleaf considers it a false result. In that case, it ignores the ol element and generates the p element.

Logical Operators

We can use logical operators with th:if and th:unless. The Thymeleaf syntax for these is as follows:

  1. Logical AND = and,
th:if = "${condition1 and condition2 and...}"
// Evaluates to true if ALL conditions are true
  1. Logical OR = or,
th:if = "${condition1 or condition2 or...}"
// Evaluates to true if ANY condition is true
  1. NOT = !, not.
th:if = "${!condition}"
// Evaluates to true when condition is false
Note

Since th:unless looks for a false result, we can accomplish the same thing by adding a not operator to a th:if statement.

The code:

<p th:unless = "${variableName == 5}">Value is NOT equal to 5.</p>

does the same thing as:

<p th:if = "${variableName != 5}">Value is NOT equal to 5.</p>

Try It!

The video below provides you some live-coding practice with Thymeleaf templates. Return to your hello-spring project and code along as you watch the clip.

Note

The starter code for this video is found at the views-static branch of hello-spring.

The final code presented in this video is found on the views-dynamic branch.

The text on this page and the previous two provides details for some of the concepts presented in the clip. Note that these summaries are NOT intended as a replacement for the walkthrough. To get better at coding, you need to actually CODE instead of just reading about how to do it.

Check Your Understanding

Assume you have an ArrayList of integers called numbers, and you display the values in an unordered list.

<ul>
    <th:block th:each = "number : ${numbers}">
        <li th:text = "${number}"></li>
    </th:block>
</ul>
Question

You want to display the list only if numbers contains data. Which of the following attributes should you add to the ul tag?

  1. th:if = "${numbers.size()}"
  2. th:unless = "${numbers.size()}"
Question

Now you want to display ONLY the positive values in the list. Which of the following attributes could you add to the li tag? Select ALL that work.

  1. th:if = "${number}"
  2. th:if = "${number < 0}"
  3. th:if = "${number > 0}"
  4. th:unless = "${number}"
  5. th:unless = "${number >= 0}"
  6. th:unless = "${number <= 0}"
Question

Now you want to display ONLY the positive, even values in the list. Which of the following should you add to the li tag?

  1. th:if = "${number > 0 and number%2 == 0}"
  2. th:if = "${number > 0 or number%2 == 0}"
  3. th:unless = "${number < 0 and number%2 == 0}"
  4. th:unless = "${number < 0 or number%2 == 0}"