Thymeleaf
Last updated
Was this helpful?
Last updated
Was this helpful?
Ich hatte bisher mit Velocity-Templating und JSPs gearbeitet. Im Zuge der Nutzung von Spring MVC/Boot haben wir Thymeleaf für ein HTML-Frontend genutzt und damit auch Email-Templates umgesetzt.
ist grundsätzlich unabhängig von der View-Technologie. Es sieht aber explizit die Nutzung von Thymeleaf für diese Aufgabe vor, was man schon daran sieht, daß Spring in den Parent-Poms als Dependency enthalten ist.
DISCLAIMER: Ich habe Thymeleaf in einer Spring-Boot-Applikation kennengelernt ... deshalb sind die Aussagen auf diesen Use-Case bezogen. In anderen Kontexten ist es möglicherweise anders.
https://github.com/thymeleaf/thymeleafexamples-petclinic
Hier findet man Best-Practices für die Thymeleaf-Nutzung.
http://www.thymeleaf.org/doc/articles/thymeleaf3migration.html
Dieses Template
sorgt für die Ausgabe
wennn zur Laufzeit diese message.properties
verwendet wird:
Wird diese Datei einfach so im Browser angezeigt, dann wird daraus (sie Natural Templating Idee)
Am Anfang hatte ich nicht genau hingeschaut und
th:text
für ein Table-Header Element gehalten. Hier gehört das aber zum Namespace http://www.thymeleaf.org und wird dementsprechend von der Thymeleaf-Template-Engine interpretiert.
Hier die Thymeleaf-Spring-Standard-DSL (= Dialekt):
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#attribute-precedence
DSL-Sprachelemente: http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
Ein praktisches Beispiel: http://spr.com/part-2-adding-views-using-thymeleaf-and-jsp-if-you-want/
JSP ist ein Generator für HTML ... Thymeleaf ist ein Generator für HTML.
JSF definiert einen Lifecycle und ist insofern deutlich komplexer. Zudem hat JSF einen View-First-Ansatz ... im Gegensatz zum Controller-First-Ansatz von JSP/Thymeleaf.
Thymeleaf arbeitet mit dem Konzept Dialekt. Ein Dialekt ist die DSL, die vom Thymeleaf ViewResolver interpretiert wird, um aus den Templates (in den die Dialekte verwendet werden) fertige Artefakte (z. B. HTML-Seiten) zu machen. Thymeleaf bringt folgende Dialekte mit:
org.thymeleaf.spring4.dialect.SpringStandardDialect
org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect
nz.net.ultraq.thymeleaf.LayoutDialect
Dialekte werden über Namespace-Definitionen im <html>
-Element eingebunden (z. B. <html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
) - es können mehrere genutzt werden.
Über entsprechende Abhängigkeiten im pom.xml
kann man weitere Dialekte verfügbar machen.
Dieser Dialekt ermöglicht eine möglichst nahtlose Integration der Thymeleaf-View-Technologie mit einem Spring-Backend. Auf diese Weise wird es möglich, in Thymeleaf-Templates Spring-Komponenten über Spring Expression Language einzubetten, um so
Daten bereitzustellen
Berechnungen/Formatierungen durchzuführen
Spring-Controller mit der Verarbeitung HTTP-Requests (POST/GET) zu beauftragen (th:action
, th:object
)
https://github.com/thymeleaf/thymeleaf-extras-springsecurity
http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#its-still-a-prototype
Verwendet man JSF als UI-Technologie, so können die JSF-Seiten (haben beispielsweise die Dateiendung *.xhtml
) im Browser ohne die dahinterliegende Applikation nicht vernünftig dargestellt werden, weil die Platzhalter nicht ersetzt sind.
Thymeleaf adressiert dieses Problem mit dem sog. Natural Templating Ansatz, so daß Thymeleaf-Templates im Browser auch ohne Ersetzung der Platzhalter vernünftig dargestellt werden. Auf diese Weise können Contentersteller und Entwickler an dem gleichen Artefakt arbeiten noch bevor an eine lauffähige Version überhaupt zu denken ist.
Hierzu werden sog. Prototypen verwendet:
In diesem Beispiel ist Willkommen zuhause ein Prototype (= Mock), der zur Laufzeit durch den Thymeleaf-Templating-Mechanismus ersetzt wird (der tatsächliche Wert kommt aus #{home.welcome}
).
Manchmal kommt es vor, daß man ohne Laufzeitumgebung gar keine Informationen bekäme. Bei dynamisch generierten Tabellen ist das beispielsweise der Fall. Hier kann man dann eine/mehrere Zeilen per th:remove="all"
als Prototyp kennzeichnen. Diese Zeile(n) werden zur Laufzeit nicht dargestellt.
href
Bei href
zeigt der Natural Templating Ansatz seine Stärke:
Dieser Link ist auch ohne Runtime-Engine - allein durch Öffnen der Seite im Browser - immer noch navigierbar, d. h. man kommt damit zur details.html
und profitiert dort wieder vom Natural Templating.
Der produktive Code ist somit gleichzeitig ein Mock.
Man kann statt der th:foo
Attribute die Expression-Language auch inline verwenden. In Ausnahmefällen ist das auch tatsächlich erforderlich (wenn das Template kein XML-Format ist) ... siehe unten Plaintext-Emails.
Statt
kann mit Inlining das geschrieben werden:
Nachteil: Man verliert dadurch aber das Natural Templating, d. h. im Browser ohne laufende Templating-Engine wird diese Seite nicht sinnvoll dargestellt.
Achtung: In Thymeleaf 3 braucht man th:inline="text"
nicht mehr ... es wird sogar empfohlen, es wegzulassen
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#standard-expression-syntax
ACHTUNG: es werden verschiedene Symbole verwendet ... je nach Content:
#{}
,${}
,*{}
,@{}
Über die Expression Language
erfolgt die Verknüpfung von statischem Content (aka Templates) und dynamischen Daten. Hier beispielsweise der Zugriff auf eine Spring-Bean:
erfolgt Internationalisierung - Einbettung von Message-Properties via
Ich empfand die Expression Language als gewöhnungsbedürftig. Das ist syntaktisch falsch
Stattdessen schreibt man
kann aber auch das schreiben:
http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html
daß Templates per Default in classpath:/templates/
gesucht werden und daß man über das Property spring.thymeleaf.prefix
(bei einer Spring Boot Anwendung gesetzt in application.properties
) diese Einstellung überschreiben kann. Diese Information findet man übrigens nicht nur im Source-Code, sondern auch in der Spring-Dokumentation:
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
Größere Anpassungen von Thymeleaf können über Spring-Annotationen erfolgen (hier in einer Spring Boot Applikation):
Hier ist ein Weg über XML-Dateien beschrieben:
http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#spring-mvc-configuration
Hat man eine Spring Boot Applikation, so ist Thymleaf über org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration.java
bereits auto-konfiguriert (sofern die Abhängigkeit zu spring-boot-starter-thymeleaf
in der pom.xml
definiert wurde). Will man dann seine eigene ThymeleafConfiguration
(siehe oben) einschieben, so muß man die Auto-Konfiguration folgendermaßen rauskonfigurieren:
Per Default verwendet Thymeleaf in einer Spring-Boot Anwendnung den org.thymeleaf.spring4.messageresolver.SpringMessageResolver
, um den Key title.homepage
zu internationalisieren.
Der Thymeleaf-SpringMessageResolver
verwendet den Spring-MessageSource
-Ansatz, d. h. defaultmässig wird eine Datei messages.properties
auf dem Classpath gesucht. Will man das Umkonfigurieren, dann hilft ein Blick in MessageSourceAutoConfiguration
.
Häufig haben Seiten einen hohen statischen Anteil und nur einen geringen dynamischen, der dann häufig auch sprachunabhängig ist. Insofern würde es Sinn machen, für jede Sprache eine eigene Datei zu verwenden - anstatt die Datei aus übersetzbaren Message-Properties zusammenzusetzen.
https://github.com/thymeleaf/thymeleaf/issues/497
http://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html
http://www.thymeleaf.org/doc/articles/sayhelloagainextendingthymeleafevenmore5minutes.html
Thymeleaf kann um eigene Dialekte erweitert werden, um so eine eigene DSL zu schaffen.
http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html
Caching abschalten (damit Änderungen an den Templates auch ohne Neustart der Applikation gezogen werden): spring.thymeleaf.cache=false
HINWEIS: in der Version 3.x wird aber auch explizit nicht-XML-Inhalt unterstützt ... beispielsweise Plain-Text-Emails.
Bei GitHub findet man dieses Beispiel:
https://github.com/thymeleaf/thymeleafexamples-springmail
Das Inlining muß aber engekündigt werden ... aber auch die Ankündigung muß an einem Element hängen, z. B. an <html>
. Damit dieses notwendige Element nicht sichtbar wird (wir wollen ja kein <html>
in den Nutzdaten haben), können wir uns eines th:remove="tag"
bedienen, das eigentlich für den Natural-Templating-Ansatz (siehe oben) vorhanden ist. Irgendwie schon sehr tricky ...
In diesem Template (emailplain.html
) wird [[${name}]]
bei diesem Code
ersetzt durch Pierre
, so daß dieses Endergebnis zu erwarten ist:
... schon tricky wie sich das künstliche html
-Element durch th:remove="tag"
selbst entfernt.
Thymeleaf wird im von Spring als View-Technologie vorgestellt. verwendet Thymeleaf beispielsweise als Default-UI-Technologie.
Thymeleaf bringt eine Auto-Konfiguration mit, die in einer Spring Boot Applikation auch automatisch gezogen wird. Man findet diese Auto-Konfiguration in der Klasse .
Thymeleaf verwendet den Standard Spring Boot Mechanismus, d. h. man findet die Konfigurationsparameter in . Darin zeigt sich beispielsweise
Thymeleaf wird in direkt supported (Bestandteil der Starter-Pakete). Es ist leicht möglich - ähnlich wie in JSF - Werte über Beans bereitzustellen, um so beispielsweise den Content einer HTML-Seite dynamisch zusammenzubauen.
DISCLAIMER: Thymeleaf hat sich - - auf XML/HTML-Content spezialisiert.
Thymeleaf 2 ist stark auf die Verwendung von XML/HTML zugeschnitten ist. Bei Plain-Text gibt es aber keine Elemente, an die sich die Thymeleaf-DSL andocken kann. Stattdessen kann verwendet werden, um zu ersetzende Elemente zu referenzieren. Dieser Ansatz läuft dem Natural Templating zuwider, weil die Platzhalter eben nicht durch Prototypen ersetzt sind. Deshalb sollte Inlining nur im äußersten Notfall eingesetzt werden.