Java D: 4,90 EUR A: 5,60 EUR CH: 9,80 CHF Benelux: 5,80 EUR ISSN 2191-6977

4 191978 304903 02 Javaaktuell mit Predictive Analytics Big Data Java imMittelpunkt Praxis. Wissen. Networking. fürEntwickler DasMagazin Framework Lagom, das neue Microservices aktuell Aus derCommunity — lung von Java SE und Vertei- Nutzung Achtung, Audit 02-2017 | Sommer | www. ijug.eu |www. 02-2017|Sommer fürdieCommunity iJUG Verbund Template-Engine

Thymeleaf – eine Template-Engine für Entwickler und Designer Gerrit Meier

In den letzten Jahren wurde mit Single Page Applications auf JavaScript-Basis immer mehr der Schritt weg vom serverseitigen Rendering gemacht. Auch die Aussage von Oracle im Rahmen der JavaOne, dass die meisten Anwendungen in der Cloud gänzlich ohne Oberfläche auskommen werden, gibt diesem Ansatz wenig Rückenwind. Warum aber erfreut sich, ganz gegen diesen Trend, die Template-Engine immer weiter steigender Nutzerzahlen? Der Artikel zeigt, was Thymeleaf anders macht und warum es gerade bei neuen Projekten eine interessante Alternative sein kann.

Bei der Entscheidung, ob eine Web-Anwen- allem durch eine übersichtliche, aber den- hen ist (siehe Abbildung 1). Im Vergleich dazu dung server- oder clientseitig gerendert wer- noch nicht einschränkend wirkende Syntax die statisch geöffnete JSP-Quelldatei (siehe den sollte, gibt es viele möglichen Faktoren, auszeichnet, existiert seit dem Jahr 2011. Abbildung 2). die man berücksichtigen und bewerten muss. Dazu gibt es eine hervorragende Integrati- Wer den Sourcecode beider Template-En- Dabei sollte, wie immer, das grundlegende on in das Spring-Ökosystem, unter anderem gines genauerer betrachtet, erkennt schnell, (Kunden-)Problem und dessen Lösung die durch einen Spring Boot Starter [2]. Auf die- dass Thymeleaf im Gegensatz zu JSP keine Hauptrolle spielen. Ist einmal die Entschei- sen Weg lassen sich sehr schnell Anwen- Custom Tags für die Logik verwendet, son- dung getroffen, sich nicht auf JavaScript- dungen unter Verwendung von Thymeleaf- dern mit Pseudo-Attributen arbeitet. Dieser Frameworks wie ReactJS oder Angular zu Templates erstellen und die ersten Schritte Ansatz, auch als „Natural Templating“ be- verlassen, sondern die HTML-Repräsentati- mit der Engine unternehmen. zeichnet, beschreibt vor allem die Nutzung on auf dem Server zu generieren, steht man der Quelldateien als Prototyp/Mocks. vor der nächsten Frage: Mit welcher Engine Natural Templating Ein großer Vorteil besteht darin, dass die soll die Seite verarbeitet werden? Vor der Besprechung der Syntax und der Entwickler diese Quelldateien etwa an einen An dieser Stelle kann zu traditionellen Funktionsweise von Thymeleaf wird ein ein- Grafiker geben können, der diese ohne eine Bibliotheken wie JavaServer Pages (JSP), faches JSP- mit einem Thymeleaf-Template laufende Anwendung auf dem Server weiter Velocity oder Freemarker gegriffen und das verglichen (siehe Listings 1 und 2). Beide Da- stylen kann. Solange die Datei direkt geöff- Rendering wie immer gelöst werden. Ein teien erzeugen die gleiche Ausgabe, wenn net und nicht durch die Engine verarbeitet Blick über den Tellerrand beziehungsweise die Seiten aus einer laufenden Anwendung wird, werden die unbekannten Attribute eine Google-Suche nach Alternativen in der aufgerufen werden. Das Besondere an Thy- vom Browser verworfen und die gemockten Java-Welt bringt einen weiteren Kandidaten meleaf ist, dass das HTML-Template auch Daten aus den bekannten Attributen und zum Vorschein: Thymeleaf [1]. statisch geöffnet werden kann und ein ge- Texten in den HTML-Tags angezeigt. Wird Das Open-Source-Projekt, das sich vor mocktes, grafisch korrektes Ergebnis zu se- die View durch einen Server ausgeliefert,

26 |

iii iii iiiiii www.ijug.eu

ersetzt Thymeleaf die Attribute, für die ent- sprechende Werte definiert wurden. Alternativ zur Standard-Syntax können auch Data Attributes verwendet werden (also „data-th-href“ statt „th:href“). So lässt sich anstelle mit unbekannten HTML-Attri- Abbildung 1: Statische Ausgabe von Thymeleaf buten, die vom Browser ignoriert werden, mit korrekten HTML5-Attributen arbeiten. Dies betrifft nur den statischen Zustand der Datei und ist aus Sicht des Autors als „nice to have“ einzuordnen. Im weiteren Verlauf gilt die Konvention, die Attribute aus dem Thymeleaf-Namespace zu nutzen.

Einfache Syntax Abbildung 2: Statische Ausgabe von JSP Wie man schon am Beispiel erkennen kann, ist die Syntax auch beim ersten Kontakt mit <%@ page contentType="text/html;charset=UTF-8" language="java" %> der Engine leicht zu verstehen. Das liegt vor <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> allem daran, dass sich Thymeleaf lediglich auf zwei Kern-Komponenten im Markup konzen- triert: Expressions und Processors. In Listing 3 sind einige grundlegenden Expressions zu sehen, die nun genauer beschrieben werden. Als Expression bezeichnet man den Ausdruck im Wert des Thymeleaf-HTML-Attributs.

In der ersten Zeile wird die wahrschein- lich bekannteste Form angetroffen, Varia- blen in einer (Java-)Web-Anwendung aus- zugeben: das Einschließen der Variablen in „${...}“. Mit diesem Ausdruck werden Werte
${jug.id}">"/>${jug.id}">${jug.name}
oder Objekte aus unserem Controller aus- gegeben beziehungsweise verwendet. Als weiterer Bekannter gehört auch der Aus- Listing 1 druck „#{...}“ zum Sprachumfang, der für die Ausgabe von fixen Strings/Messages wie „i18n“-Properties verwendet werden kann. Bis jetzt wurde für die meist verwende- ten Zugriffsarten auf Werte oder Objekte keine neue Syntax eingeführt, sodass hier JUG List schon zu erkennen ist, dass die Lernkurve wenig mehr Komfort sein, kann man auf die Expression *{...} zurückgreifen. Wie in den Zeilen drei bis fünf zu sehen ist, wird mit gegriffen, dessen Attribute werden direkt referenziert. Falls kein äußeres Objekt vor-
Meine Jug
handen ist, verhält sich dieser Ausdruck wie der genannte Variablen-Zugriff per ${...}. Sehr nützlich ist die URL-Expression „@ Listing 2 {...}“. In Listing 3 sind mehrere Beispiele zu sehen, allen voran die Verwendung von re- lativen Pfaden in der Anwendung. Hier wird der Context-Pfad der Anwendung auto- ren. Dies bietet zum Beispiel den Vorteil, dabei mit oder ohne Platzhalter erfolgen. matisch ermittelt und ergänzt, sodass ein dass mit relativ elegantem Code in Schlei- Dies führt im ersten Beispiel zu einem Link komplexes beziehungsweise unschönes fen bei jedem Eintrag auf die gleiche URL mit Query-Parameter und im zweiten zur Präfixen per Hand nicht notwendig ist. URL- mit unterschiedlichen Parametern gemappt Ersetzung des Platzhalters. Expressions lassen sich auch parametrisie- werden kann. Die Parametrisierung kann Soll ein Link doch einmal auf eine andere

Java aktuell 2-2017 | 27 Template-Engine

Anwendung auf dem Server oder ein ganz Platzhalter Platzhalter anderes System zeigen, kann dieses auch in den URL-Expressions mit angegeben

Platzhalter werden. Dabei wird der URL ein „~“ (Server
relativ) beziehungsweise ein „//“ (Protocol relative) vorangestellt. Im zweiten Fall kann JUGs alternativ auch die vollständige URL inklu- JUG Details sive Protokoll in der Expression verwendet JUG Details werden. Dies schafft jedoch eine Bindung an eine andere Anwendung das Protokoll und erzwingt den Einsatz von ein anderer Server Environment-Configs, um beispielsweise im Listing 3 Testbetrieb jeglichen Datenverkehr mit an- deren Systemen über HTTP anstatt HTTPS laufen zu lassen.

Reintext Processors unescaped Text Unter „Processor“ wird im Thymeleaf- Meine JUG: [[${jug.name}]]! Kontext nicht nur das verwendete HTML- Listing 4 Attribut verstanden, sondern auch seine dahinterliegende Logik und das Resultat bei der Verarbeitung durch die Engine. In Thy- meleaf steht eine theoretisch überschauba- re Anzahl von Processors zur Verwendung erste JUG bereit. Theoretisch aus dem Grund, weil es für jedes denkbare Standard-HTML5-Attri- zweite JUG but einen Processor gibt. Diese sind intuitiv so benannt, dass man nur vor das Attribut dritte JUG ein „th:“ einfügen muss, um den passenden Processor zu bekommen. Die wichtigste Funktion einer Template- Listing 5 Engine ist wahrscheinlich die Ausgabe von Informationen, also Text. Um Text in ein HTML-Tag unter der Verwendung von Pro- cessors auszugeben, werden die Attribute „th:text“ beziehungsweise „th:utext“ ver- wendet (siehe Listing 4). Dies ist, wenn es erste JUG sich als geeigneter erweist, auch durch den Processor „th:inline“ und das Schreiben des zweite JUG auszugebenden Texts in einer Inline-Form möglich. Es ist bei dieser Expression egal, dritte JUG ob die Ausgabe direkt als Kind oder in einer tieferen Ebene erscheinen soll. Dabei sollte beachtet werden, dass in diesem Fall die Listing 6 Ausgabe des Platzhalters beim Öffnen der Quelldatei immer zu sehen ist und nicht durch einen prototypischen Wert ersetzt werden kann.

Schleifen und Beispiel-Daten Viele Anwendungen basieren auf der Anzei- ge von Listen, Tabellen oder ähnlichen Dar- stellungsformen, die meist in einer Schleife ausgegeben werden. Hier bietet Thymeleaf mit „th:each“ (siehe Listing 5) genau eine Lö- sung, um Daten aus einer Sammlung (Itera- ble, Map, Array etc.) zu durchlaufen. Nun be-
erste JUG
zweite JUG
dritte JUG
steht eine der beworbenen Besonderheiten Listing 7 der Engine darin, dass mit gemockten Daten

28 |

iii iii iiiiii www.ijug.eu

gearbeitet werden kann. doch etwas Vorsicht geboten, da hier nicht Schleifen realisiert werden, aber kein El- Wenn das Beispiel in der Form auf dem nur pauschal auf einen booleschen Wert im tern-Element verwendet werden kann, das Server aufgerufen wird, bekommt man nicht Java-Sinn zu achten ist. Abhängig von der als Iterations-Anfang dient. Das Element nur die Werte geliefert, die unsere Anwen- Art des Objekts beziehungsweise seines wird nach der Verarbeitung nicht an den dung bereitstellt, sondern am Ende auch Werts ergeben sich folgende Möglichkeiten Browser ausgeliefert, erzeugt jedoch in der noch die Mock-Daten. Um dieses Problem für true: Boolean mit dem Wert „true“, eine statischen Ansicht durch das unbekannte zu umgehen, wurde ein weiterer Processor Zahl oder ein Character ungleich „0“ oder ein HTML-Tag Fehler im HTML-Source. Wen die- („th:remove“) bereitgestellt (siehe Listing 6). String, der nicht „no“, „false“ oder „off“ als se stören, der kann diesen Block mit einem Wie der Name schon erraten lässt, entfernt Wert hat. bestimmten Kommentar sowohl vom Brow- dieser je nach gewähltem Wert etwa den Soll es zu einer Fall-Unterscheidung ser ignorieren als aber auch von der Engine ganzen Tag („all“), alle Kinder („body“) oder kommen, sollte man anstelle von komplexen erkennen lassen. alle Kinder bis auf das erste („all-but-first“). „if“-Kaskaden die Processors „th:switch“ Bei Verwendung des letztgenannten Werts und „th:case“ verwenden. In Thymeleaf gibt Templating kann genau das gewünschte Verhalten er- es keinen Fallthrough, sondern der erste Durch die Verwendung von Fragments, ei- reicht werden: Nach dem Rendern werden zutreffende Case wird verwendet. Um den nem weiteren Processor, ist es möglich, nur noch die echten Daten aus der Anwen- Default-Fall abzufangen, gibt es den spezi- einfaches Templating mit Thymeleaf vorzu- dung angezeigt und die gemockten Elemen- ellen Wert „th:case="*"“. nehmen (siehe Listing 8). Die Definition der te sind entfernt. einzufügenden Inhalte erfolgt dabei in einer Der Block-Prozessor ausgelagerten HTML-Datei (siehe Listing 9). Bedingungen Da Ausnahmen die Regel bestätigen, hat So ergibt sich wieder der Vorteil, dass das Für die Abfrage von Bedingungen gibt es in auch Thymeleaf seine ganz eigene Ausnah- zu inkludierende Fragment in ein vollstän- Thymeleaf wiederum eine überschaubare me, den Blockprozessor. Wie in Listing 7 zu diges HTML-Dokument eingebettet werden Anzahl von Processors. Bedingungsabfra- sehen ist, ist dieser Processor kein HTML- kann, um es statisch zu bearbeiten. Bevor gen lassen sich durch „th:if“ beziehungs- Attribut, sondern ein − genau genommen das Einbetten der Fragmente gezeigt wird, weise invers durch „th:unless“ realisieren. das einzige − HTML-Tag in der Thymeleaf- sei an dieser Stelle der Hinweis gegeben, Bei der Verwendung der Expression ist je- Welt. Er wird vor allem verwendet, wenn dass es bei komplexeren Fragmenten auch

NIK IST EXPERTE FÜR KOFFEIN SAXOPHON

UND WEB DESIGN

BE YOURSELF AND MAKE A DIFFERENCE Jetzt bewerben auf accenture.com/MakeADi erence Java#MakeADi aktuell 2-2017 erence| 29 Template-Engine

zu einem komplexen Mocking in der Haupt-

seite kommen kann.
Das Hinzuziehen von HTML-Bestandtei-
len aus anderen Dateien ist intuitiv mit der Listing 8 Wahl einer von drei unterschiedlichen Ein- bindungsarten möglich. Zur Auswahl stehen „th:insert“ (ab Thymeleaf 3), „th:replace“ und „th:include“, die dazu führen, dass ein Frag- ment entweder komplett als Kind eingefügt, das Tag in der Hauptseite ersetzt oder nur Footer dummy der Inhalt des Fragments in die Hauptseite übernommen wird. Dabei bezieht man sich
beim Referenzieren immer auf den Datei- footer text und definierten Fragmentnamen.
Fragmente sind darüber hinaus auch pa- rametrisierbar und lassen sich somit sehr flexibel einsetzen. Ein möglicher Anwen- Listing 9 dungsfall wäre, eine Breadcrumb-Bar in ein Fragment auszulagern und den Besuchs- beziehungsweise Navigationsverlauf über Parameter für die Visualisierung mitzugeben. Faktor ist, dass bei der Erstellung dieses stoßen, kann die Datei einfach von einem Artikels der Support für die aktuelle Version Designer bearbeitet werden, ohne dass Kleine Helfer in Spring Boot, mit dem man sehr schnell Thymeleaf die Views zuerst verarbeitet Damit das Hantieren mit unterschiedlichen Thymeleaf-Projekte erstellen kann, noch haben muss. Vor allem im Gegensatz zu Objekt-Typen mehr Komfort bietet, stehen nicht existierte (siehe „https://github.com/ dem doch etwas angestaubten JSP bringt unterschiedliche Helfer-Objekte („Expres- spring-projects/spring-boot/issues/7450)“. Thymeleaf wieder frischen Wind in die Ent- sions Utility Objects“) bereit, um dem Ent- Man muss jedoch keine Angst davor haben, wicklung von serverseitig gerenderten Web- wickler unter die Arme zu greifen. Da wären Templates unter Verwendung der Version Anwendungen. zum einen Methoden, die mit Collections 2.1 zu erstellen. Sie lassen sich später auf (Lists, Set, Maps, Arrays) arbeiten und prak- Version 3 migrieren. Weiterführende Links tische Funktionalität wie „contains“, „isEm- Thymeleaf 3 zeichnet sich vor allem [1] Thymeleaf: http://www.thymeleaf.org [2] Spring Boot: http://start.spring.io pty“ oder „sort“ anbieten. Hinzu kommt ein durch ein annähernd komplettes Rewrite [3] Thymeleaf Extensions: http://www.thymeleaf. guter Support für Datums-, Zahlen- und der Engine, unter Rücksichtnahme auf die org/ecosystem.html [4] Spring Data Extension: https://github.com/ String-Objekte, der viele üblichen Zugriffe aktuellen Anforderungen, aus. So wurden jpenren/thymeleaf-spring-data-dialect oder Operationen abdeckt. Zwei String- zum Beispiel die Processor- und Dialect- Methoden, die hier als Beispiel des Umfangs APIs, die in erster Linie den Erweiterungen erwähnt sind, lauten „listJoin“ und „listSplit“. der Engine dienen, noch zugänglicher ge- Gerrit Meier Damit lassen sich Listen-Inhalte in einen staltet. Es existieren sowohl offizielle als [email protected] konkatenierten String verwandeln bezie- auch Community-getriebene Extensions [3], hungsweise anhand eines Trennzeichens die an dieser Stelle ansetzen. Beispielsweise eine Liste anlegen. kann man mit dem thymeleaf-spring-data- Gerade an solchen Stellen erkennt man, dialect [4] komfortabel Pagination in den dass die Entwickler der Engine nicht nur Views ohne viel Eigenaufwand realisieren. das Nötigste anbieten, sondern auch dem Nutzer helfen, Probleme auf eine elegante Weise zu lösen. Richtig eingesetzt, können Fazit die Utility Objects somit sowohl zur Funk- Wer sauberen und wartbaren Code in seinen tionalität als auch zur Lesbarkeit des Codes Views haben und zeitgemäße Template-En- beitragen. gines einsetzen möchte, dem sei Thymeleaf ans Herz gelegt. Basiert das aktuelle Projekt Gerrit Meier beschäftigt sich beruflich hauptsäch- Ausblick auf Spring Boot, bekommt man unter Zuhil- lich mit Themen aus dem Umfeld der (Java-)Web- Dieser Artikel basiert größtenteils auf der fenahme eines Thymeleaf-Starters die pas- Entwicklung. Neue Technologien, Ideen und Ansätze Version 2.1 von Thymeleaf, obwohl schon sende Konfiguration mitgeliefert. Will man − auch abseits seines technologischen Schwerpunkts seit Mai letzten Jahres die Version 3 verfüg- sich nicht an Spring Boot binden, die Engine − motivieren ihn immer wieder zum Ausprobieren und bar ist. Grund dafür ist, dass es bei den an- aber dennoch in einer Spring-Anwendung Verstehen. Da er dies als eine wichtige Kompetenz von gesprochenen Features wenig bis gar keine nutzen, so bietet Thymeleaf Support für die Entwicklern sieht, bemüht er sich, dieses Wissen und Änderungen in der Nutzung gibt. Ein wei- Versionen 3, 4 und 5 (Milestone Releases). den Spaß am „Einfach-mal-Machen“ weiterzuvermit- terer und eigentlich der ausschlaggebende Wenn die Entwickler an ihre CSS-Grenzen teln. Gerrit ist Co-Organisator der JUG Ostfalen.

30 |