Refresh
this page because I am probably still making changes
to it.
In the previous lesson you learned
how to make data accessible in the response by using
Model attributes. This allows you to dynamically add data to the
response so that it's sent back to the client. For example, you can
configure an HTML page to show a collection of book data retrieved on the
server, and that book data is embedded in the HTML page and sent back to the
client in the response.
Recall that Thymeleaf is a template engine.
We can create an HTML page and include Thmeleaf code to
format how dynamic data appears and even include expressions and calculations.
This is exactly what the /templates directory
of your /resources directory is for!
Thymeleaf is coded by adding special thymeleaf expressions inside
Thymeleaf attributes (such as th:text)
added to HTML elements. All Thymeleaf attributes
are prefixed with th:, so they're part of the Thymeleaf
namespace. That way, they won't get confused with the existing
HTML attributes.
Let's begin by learning the syntax of Thymeleaf expressions and
the different attributes you can use (tip: you already know all the
attributes!)
Pre-Requisites
For this lesson, it's important that you've already learned how to
use Model Attributes from the
Introduction to Thymeleaf lesson.
The ${ } part of the expression you learned in the
previous lesson is a
variable expression. Inside the curly
braces you can put any object variable or object property, a model attribute,
an implicit object, etc.
Variable expressions can contain operators. For example,
all the basic mathematical operations are supported:
Arithmetic Operators
Sample Expression
Result
Comments
${12.5 + 4}
16.5
${1.25E3 + 4}
1254
1.25E3 is exponential notation for 1250
${15 % 6}
3
${2 + 3 * 4}
14
${(2 + 3) * 4}
20
${15 > 100}
false
Some variable expressions can also evaluate to a boolean
value, so the standard relational operations are
supported. Note however, that you can't place
a < or > symbol inside an HTML attribute value,
so you'll have to use
character entities such as < and >
or use the alternative operators lt and
gt (more of these are outlined further down).
Boolean Expressions
Sample Expression
Result
Comments
${"foo" == "foo"}
true
compares string value
${"foo" == "bar"}
false
compares string value
${"foo" != "foo"}
false
${fabric == "FAUX_FUR"}
When comparing enum constants, treat them as a String literal.
In this example, "FAUX_FUR" will automatically be converted
to a Fabric enum value before being compared, it's just like
typing fabric == Fabric.FAUX_FUR in Java.
${"foo" == "foo" && 15 > 100}
false
note you can't use
> or < symbols in an expression so you have to character entities or one
of the alternate text operators (see table below)
${"foo" == "foo" && 15 <= 100}
true
note you can't use
> or < symbols in an expression so you have to character entities or one
of the alternate text operators (see table below)
${!(15 gt 100)}
true
note you can't use
> or < symbols in an expression so you have to character entities or one
of the alternate text operators (see table below)
String operations are also supported.
Concatenation is done with the + operator.
You can perform literal substitution
using the |
(pipe, vertical line) symbol. For example:
Most of the operators discussed above have alternative
symbolism that uses letters. As mentioned earlier, you can't use
certain operators such as < and > inside an HTML attribute,
so many developers use the alternatives, isntead.
The table below outlines the
different operators and their symbols and alternatives:
Expression Operators
Arithmetic Operators
Operator
Alternative
Example
+
${12.5 + 4}
-
${12.5 - 4}
*
${12.5 * 4}
/
div
${12.5 / 4} ${12.5 div 4}
%
mod
${15 % 6} ${15 mod 6}
Relational Operators
Operator
Alternative
Example
==
eq
${"foo" == "foo"} ${"foo" eq "foo"}
!=
ne
${"foo" == "foo"} ${"foo" ne "foo"}
<
lt
${x < y} ${x lt y}
>
gt
${x > y} ${x gt y}
<=
le
${x <= y} ${x le y}
>=
ge
${x >= y} ${x ge y}
Logical Operators
Operator
Alternative
Example
&&
and
${customer.active && customer.balance > 100}
${customer.active and customer.balance > 100}
||
or
${customer.active || customer.balance <= 100}
${customer.active or customer.balance <= 100}
!
not
${!customer.active}
${not customer.active}
Unescaped Text
Normally when you use th:text,
any special HTML characters are escaped. So if you had
a model attribute called "output" with the content
"<span class='foo'>Foo!</span>"
and you then wrote the Thymeleaf code:
<p th:text="${output}"></p>
The value assigned to th:text would be parsed and sent
back in the response body as
<p><span class='foo'>Foo!</span></p>
So that would actually render on the page as a paragraph
element containing the content
<span class='foo'>Foo!</span>
Try it in your own program and you'll see what I mean!
If you want to display text that has any HTML code in it,
and you want that code to be treated like actual HTML code
(where the special characters aren't escaped and the HTML
code is actually rendered as pure HTML)
you should use th:utext
instead. The th:utext
attribute will not escape any special HTML characters such as
<, >, &, etc.
Give it a try, add a model attribute in your handler
method with some HTML, such as:
model.addAttribute("test", "How does <strong>this</strong> display?");
Display the attribute on your output page using a paragraph
or div with th:text and a different paragraph/div using th:utext.
Check the source after you reload your page.
Exercise
Try out some basic Thymeleaf expressions: start a new project (add dependencies for
Spring Web, Dev Tools, Thymeleaf, and Lombok) and add
a controller and an HTML page index.html in the /templates
directory. Make sure you add the Thymeleaf namespace to the
<html> element of your page. Add your Book bean to your project's
.beans package.
In a handler for the index page, add some model attributes:
Model Attribute
Value
firstName
your first name
lastName
your last name
number
your favourite number, any number
book
a book object that you will have to instantiate
Add these template objects with Thymeleaf expressions to your page
(don't forget to include fallback text):
Add a level-1 heading containing your first name and last name.
Add a paragraph or div element that displays
true if your number is even and false if your number is odd.
A paragraph or div element with the book object's title,
followed by " by ", followed by the book's author.
A paragraph or div element with the result of your number
times the price of the book.
You might find there are several ways to do the same thing.
For example, all of these produce the exact same output:
Is one of these solutions better than another? It depends
on what you want to do with the rest of your page.
If you wanted to style the individual attribte values,
Solution 3 would be better because
you can easily create different CSS classes for each SPAN
nested inside the P element. If you wanted to use fewer
elements (to make the DOM more efficient), you might
prefer Solution 1 or 2.
Referencing CSS and Images
When referencing external resources, you have to use a
URL expression instead of a variable expression. A URL
expression uses @{ }. Inside
the curly braces, you put the location of the resource.
If the resource is a file, make sure it starts with the
forward-slash / if you're referencing it from the context
path.
Recall that all web resources such as images, scripts, and
CSS files are stored in the /static directory. Always
reference the /static directory in a URL expression with
a forward slash, followed by the file or sub-directory
that resides inside /static. For example, assuming
you have an image file "picture.jpg" inside /static/images,
your URL expression would be
@{/images/picture.jpg}
Therefore, adding such an image to an HTML page using Thymeleaf
would be something like:
Note that we should still include the static image src attribute
as a fallback!
You can do something similar with an external CSS file: assuming you
follow the industry standard and have a /css or /styles directory
in your /static directory, you can link to a CSS file from any
static page normally. From a /templates page, you would use a link
tag such as:
Once again, notice that you should include the regular href
attribute as fallback code.
Thymeleaf Attributes
What else can you do with Thymeleaf? To be honest, there
is just SO MUCH you can do that we are unable to cover
it all in this course, so make sure you take some time
later to go over the
Thymeleaf tutorial, and make note
of the Thymeleaf documentation
in case you ever want to
search for how to do something specific.
Attribute Modifiers
Attribute modifiers are Thymeleaf versions of existing
HTML attributes. Most of the HTML5 attributes have
a Thymeleaf version, such as th:class,
th:name, th:id,
th:action, th:alt,
th:for, th:href,
th:pattern, th:placeholder,
th:src, th:style,
th:target,
th:title, and
th:value. There are several others: obviously
listing them all here is not practical.
All of these types of attributes can be used with Thymeleaf
expressions. For example:
In this example, an input element is using
th:value to assign a dynamic value to the input field,
which in this case is whatever is inside inv.itemName.
Notice we are also including value="Item Name" as a fallback:
if for some reason Thymeleaf isn't working, the input
field's value will be "Item Name".
Exercise
Start a new project and add the dependencies for Spring Boot,
Dev Tools, Thymeleaf, and Lombok. Add your book bean and a
controller to the project, along with an index HTML page.
On your index page, create a form that allows a user to enter
book information.
In the controller, add a handler method that loads the
index page. Instantiate a Book object and add it to the
Model as an attribute.
Now go back to your form and add the th:value attribute
to each input field so that the fields contain the
existing book object's data when the index page loads.