Thymeleaf – template engine dla Spring

TL;DR: Thymeleaf to nowoczesny template engine dla Spring MVC który pozwala tworzyć naturalne HTML templates – pliki które można otwierać w przeglądarce bez uruchamiania aplikacji. Używa własnego expression language i świetnie integruje się z Spring ecosystem.

Dlaczego Thymeleaf zmienia sposób myślenia o templates?

Tradycyjne template engines jak JSP tworzą pliki które są nieczytelne w surowej formie. Thymeleaf rewolucjonizuje to podejście – tworzy „natural templates” które wyglądają jak normalne HTML i można je otwierać bezpośrednio w przeglądarce. To jak różnica między pisaniem surowego kodu assembly a wysokopoziomowym językiem programowania.

Thymeleaf 3.0 (wydany w maju 2016) wprowadził znaczne usprawnienia wydajności i jest domyślnym template engine w Spring Boot 1.4+.

Co się nauczysz:

  • Podstawy składni Thymeleaf i natural templates concept
  • Integration z Spring MVC i model attributes
  • Thymeleaf Standard Expression Language
  • Iteracje, warunki i fragmenty w templates
  • Formularze i walidacja z Spring Forms integration
Wymagania wstępne: Podstawy Spring MVC, znajomość HTML i CSS, pojęcie Model-View-Controller pattern, doświadczenie z web development.

Czym jest Thymeleaf?

Thymeleaf to server-side Java template engine dla web applications. W przeciwieństwie do JSP, tworzy „natural templates” – HTML files które mogą być wyświetlane w przeglądarce nawet bez przetwarzania przez serwer.

Natural Templates – template files które są valid HTML/XML i mogą być otwierane bezpośrednio w przeglądarce, wyświetlając prototyp strony z placeholder content.

Thymeleaf vs JSP – porównanie

AspektJSPThymeleaf
CzytelnośćMieszanka HTML + Java codeCzyste HTML + attributes
PrototypingNie można otwierać w przeglądarceNatural templates
IDE SupportOgraniczoneExcellent HTML tooling
TestowanieWymaga servlet containerUnit testing możliwe
PerformanceBardzo szybkieSzybkie (Thymeleaf 3.0+)

Podstawy składni Thymeleaf

Pierwszy template





    
    Hello Thymeleaf


    
    

Hello, [Prototype Name]!

Hello, [Name]!

User status placeholder

Current time: 01/01/2017 12:00

Spring Controller integration

@Controller
public class HelloController {
    
    @GetMapping("/hello")
    public String hello(@RequestParam(defaultValue = "World") String name, 
                       Model model) {
        
        // Dodanie danych do model
        model.addAttribute("name", name);
        model.addAttribute("currentDate", new Date());
        
        User user = new User("john_doe", true);
        model.addAttribute("user", user);
        
        // Zwraca nazwę template (hello.html)
        return "hello";
    }
}
Pro tip: Thymeleaf automatycznie rozpoznaje templates w src/main/resources/templates/ w Spring Boot. Nie musisz konfigurować view resolver.

Standard Expression Language

Typy expressions w Thymeleaf


First Name

Last Name

First Name

Last Name

Welcome message

User Profile Search Results
Header placeholder

Utility objects


01 Jan 2017

USER NAME

No description

99.99

5 users found

No orders

Age category

Iteracje i kolekcje

Lista użytkowników


# Name Email Status
1 John Doe john@example.com Active Inactive
No users found

Controller dla listy

@Controller
@RequestMapping("/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping
    public String listUsers(Model model) {
        List users = userService.findAll();
        model.addAttribute("users", users);
        return "users";
    }
    
    @GetMapping("/{id}")
    public String userDetail(@PathVariable Long id, Model model) {
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "user-detail";
    }
}
Pułapka: W th:each iterStat zawiera przydatne properties: index (0-based), count (1-based), size, current, even/odd, first/last.

Formularze i Spring Forms integration

Form z model binding


First name error
Email error

Controller z walidacją

@Controller
@RequestMapping("/users")
public class UserFormController {
    
    @GetMapping("/new")
    public String newUserForm(Model model) {
        model.addAttribute("user", new User());
        return "user-form";
    }
    
    @GetMapping("/{id}/edit")
    public String editUserForm(@PathVariable Long id, Model model) {
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "user-form";
    }
    
    @PostMapping
    public String saveUser(@Valid @ModelAttribute User user, 
                          BindingResult bindingResult, 
                          Model model) {
        
        if (bindingResult.hasErrors()) {
            return "user-form";
        }
        
        userService.save(user);
        return "redirect:/users";
    }
}

Fragmenty i layouts

Reusable fragments






© 2017 My Application. All rights reserved.

User Name

user@example.com

View Profile

Użycie fragmentów





    
    User Management
    


    
    

Recent Users

Pro tip: Użyj th:insert dla including całego fragmentu, th:replace dla replacement elementu, lub th:include dla including tylko zawartości fragmentu.

Internationalization (i18n)

Messages properties

# messages.properties (default)
welcome.message=Welcome to our application
user.firstName=First Name
user.lastName=Last Name
user.email=Email Address
button.save=Save
button.cancel=Cancel

# messages_pl.properties (Polish)
welcome.message=Witamy w naszej aplikacji
user.firstName=Imię
user.lastName=Nazwisko
user.email=Adres email
button.save=Zapisz
button.cancel=Anuluj

Użycie w template


Cancel

Czy Thymeleaf jest szybszy od JSP?

Thymeleaf 3.0 ma porównywalną wydajność z JSP. Wcześniejsze wersje były wolniejsze, ale 3.0 wprowadził engine rewrite z focus na performance. Dla większości aplikacji różnica jest negligible.

Jak debugować Thymeleaf templates?

Użyj Spring Boot DevTools dla hot reload. W IntelliJ/Eclipse masz syntax highlighting i code completion. Dodaj logging.level.org.thymeleaf=DEBUG dla detailed processing info.

Czy mogę mieszać Thymeleaf z JSP w jednej aplikacji?

Technicznie tak, ale nie jest to recommended practice. Lepiej migrować stopniowo – zacząć od nowych views w Thymeleaf i postupowo refactorować istniejące JSP.

Jak używać JavaScript z Thymeleaf?

Możesz inline JavaScript z th:inline=”javascript” i używać [[${variable}]] syntax. Dla complex frontend logic lepiej użyć REST API i separate JavaScript framework.

Czy Thymeleaf wspiera caching?

Tak, Thymeleaf cachuje parsed templates. W development mode cache jest disabled (spring.thymeleaf.cache=false), w production włączony domyślnie dla performance.

🚀 Zadanie dla Ciebie

Stwórz kompletną aplikację CRUD z Thymeleaf:

  1. Model: Product z polami: name, price, description, category
  2. Lista produktów z paginacją i filtrowaniem
  3. Formularz create/edit z walidacją (JSR-303)
  4. Fragment layout z header, footer i navigation
  5. Internationalization – obsługa PL i EN
  6. Bootstrap styling dla professional look

Test natural templates – otwórz pliki HTML bezpośrednio w przeglądarce i sprawdź czy wyglądają sensownie jako prototypy.

Przydatne zasoby:

Używasz Thymeleaf w swoich projektach Spring? Jakie są największe zalety natural templates w porównaniu z JSP w twoim doświadczeniu?

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Przewijanie do góry