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 ``
`` element.
Instead, the template could include a ```` 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:
.. sourcecode:: groovy
th:if = "${condition}"
#. The ``th:if`` statement gets placed inside an HTML tag.
#. ``condition`` represents a boolean variable provided by the controller.
#. 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.
.. admonition:: Example
Assume that ``coffeeOptions`` and ``userSelection`` represent an ArrayList
and String, respectively, that are passed in by the controller.
.. sourcecode:: html
:linenos:
You can do better!
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:
#. If ``condition`` is a boolean or statement and ``true``.
#. If ``condition`` is a non-zero number or character.
#. If ``condition`` is a string that is NOT ``"false"``, ``"off"``, or
``"no"``.
#. 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``:
.. sourcecode:: groovy
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``:
.. admonition:: Example
.. sourcecode:: html
:linenos:
Excellent choice!
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``.
.. admonition:: Example
.. sourcecode:: html
:linenos:
No coffee brewed!
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:
#. Logical AND = ``and``,
.. sourcecode:: groovy
th:if = "${condition1 and condition2 and...}"
// Evaluates to true if ALL conditions are true
#. Logical OR = ``or``,
.. sourcecode:: groovy
th:if = "${condition1 or condition2 or...}"
// Evaluates to true if ANY condition is true
#. NOT = ``!``, ``not``.
.. sourcecode:: groovy
th:if = "${!condition}"
// Evaluates to true when condition is false
.. admonition:: 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:
.. sourcecode:: groovy
Value is NOT equal to 5.
does the same thing as:
.. sourcecode:: groovy
Value is NOT equal to 5.
.. _hello-spring-vid2:
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.
.. youtube::
:video_id: bT5Zt9xZYSU
.. admonition:: Note
The starter code for this video is found at the
`views-static `__ branch of ``hello-spring-demo``.
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.
.. sourcecode:: html
:linenos:
.. admonition:: Question
You want to display the list only if ``numbers`` contains data. Which of the
following attributes should you add to the ``ul`` tag?
#. ``th:if = "${numbers.size()}"``
#. ``th:unless = "${numbers.size()}"``
.. Answer = a
.. admonition:: 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.
#. ``th:if = "${number}"``
#. ``th:if = "${number < 0}"``
#. ``th:if = "${number > 0}"``
#. ``th:unless = "${number}"``
#. ``th:unless = "${number >= 0}"``
#. ``th:unless = "${number <= 0}"``
.. Answers = c and f
.. admonition:: 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?
#. ``th:if = "${number > 0 and number%2 == 0}"``
#. ``th:if = "${number > 0 or number%2 == 0}"``
#. ``th:unless = "${number < 0 and number%2 == 0}"``
#. ``th:unless = "${number < 0 or number%2 == 0}"``
.. Answer = a