Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text.
The main goal of Thymeleaf is to provide an elegant and highly-maintainable way of creating templates. To achieve this, it builds on the concept of Natural Templates to inject its logic into template files in a way that doesn’t affect the template from being used as a design prototype. This improves communication of design and bridges the gap between design and development teams.
Thymeleaf has also been designed from the beginning with Web Standards in mind – especially HTML5 – allowing you to create fully validating templates if that is a need for you.
The Good Thymes Virtual Grocery
To better explain the concepts involved in processing templates with Thymeleaf, this tutorial will use a demo application which you can download from the project’s web site.
This application is the web site of an imaginary virtual grocery, and will provide us with many scenarios to showcase Thymeleaf’s many features.
To start, we need a simple set of model entities for our application: Products which are sold to Customers by creating Orders. We will also be managing Comments about those Products:
Our application will also have a very simple service layer, composed by Service objects containing methods like:
public class ProductService {
...
public List<Product> findAll() {
return ProductRepository.getInstance().findAll();
}
public Product findById(Integer id) {
return ProductRepository.getInstance().findById(id);
}
}
Our first task will be to create a home page for our grocery site.
The first version of this page will be extremely simple: just a title and a welcome message. This is our /WEB-INF/templates/home.html file:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head>
<body>
<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
</body>
</html>
Standard Expression Syntax
We will take a small break in the development of our grocery virtual store to learn about one of the most important parts of the Thymeleaf Standard Dialect: the Thymeleaf Standard Expression syntax.
We have already seen two types of valid attribute values expressed in this syntax: message and variable expressions:
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
<p>Today is: <span th:text="${today}">13 february 2011</span></p>
But there are more types of expressions, and more interesting details to learn about the ones we already know. First, let’s see a quick summary of the Standard Expression features:
- Simple expressions:
- Variable Expressions:
${...}
- Selection Variable Expressions:
*{...}
- Message Expressions:
#{...}
- Link URL Expressions:
@{...}
- Fragment Expressions:
~{...}
- Literals
- Text literals:
'one text'
, 'Another one!'
,…
- Number literals:
0
, 34
, 3.0
, 12.3
,…
- Boolean literals:
true
, false
- Null literal:
null
- Literal tokens:
one
, sometext
, main
,…
- Text operations:
- String concatenation:
+
- Literal substitutions:
|The name is ${name}|
- Arithmetic operations:
- Binary operators:
+
, -
, *
, /
, %
- Minus sign (unary operator):
-
- Boolean operations:
- Binary operators:
and
, or
- Boolean negation (unary operator):
!
, not
- Comparisons and equality:
- Comparators:
>
, <
, >=
, <=
(gt
, lt
, ge
, le
)
- Equality operators:
==
, !=
(eq
, ne
)
- Conditional operators:
- If-then:
(if) ? (then)
- If-then-else:
(if) ? (then) : (else)
- Default:
(value) ?: (defaultvalue)
- Special tokens:
This chapter will explain the way in which we can set (or modify) values of attributes in our markup.
Say our website publishes a newsletter, and we want our users to be able to subscribe to it, so we create a /WEB-INF/templates/subscribe.html template with a form:
<form action="subscribe.html">
<fieldset>
<input type="text" name="email" />
<input type="submit" value="Subscribe!" />
</fieldset>
</form>