a Founder and Lead Developer of Thymeleaf. He kindly gave me some advices for my presentation and allow me to use his session materials of Devoxx Belgium 2015 and Spring I/O 2016. Special Thanks! The Thymeleaf Artwork by The Thymeleaf Project is licensed under the Creative Commons CC BY-SA 3.0 License.
for Java • Open Source — Apache 2.0 License • First version 2011 — Currently 3.0.0 • Processes HTML, XML, JavaScript, CSS, Text • View layer in Spring MVC apps • Also MVC 1.0, vert.x, ratpack, Spring Reactive
valid as the final result, the engine syntax doesn't break the document's structure” [Comparison of web template engines - Wikipedia, the free encyclopedia] Natural Templates What is Thymeleaf? https://en.wikipedia.org/wiki/Comparison_of_web_template_engines
Thymeleaf? • No need for double attributes: • src + th:src, href + th:href • No need for prototyping text • Expressions can be inlined <tr> <td><img th:src="@{/images/logo.png}"/></td> <td>Welcome to our e-shop, [[${session.user.name}]].</ td> </tr>
&, " and ‘ will be escaped (in Html mode) • Unescaped processor is “th:utext” <p th:text="${user.name}">James Carrot</p> HtmlEscape.escapeHtml4Xml(unbescape) http://goo.gl/MDQr8E <p>Mitsuyuki Shiiba</p> output of running webapp
the 3.0 branch started July 2014 • AttoParser is started in late 2012 • Almost complete rewrite of the engine • 63K+ lines of code 85% new • 77K+ lines of test 40% new • 220 listres of coffee 100% arabica
• No longer XML-based • Created from scratch with Thymeleaf in mind <div ng-app><p th:text=${mytext}>Whatever valid template! http://www.attoparser.org/
Application. I created thymeleaf3-spring-boot. You can use it until the official one is released. There are only 2 steps. 1. Modify pom.xml 2. Add an exclude paramter https://github.com/bufferings/thymeleaf3-spring-boot
make sure you don’t have any “[[xxx]]” syntax in your html and especially in your JavaScript code. • If you use extra libraries, please check it supports Thymeleaf 3.0
... ]]> in <script> or <style> 1. New Template Mode <script> /*<![CDATA[*/ var user = ... if (user.signupYear < 1990) { alert('You\'ve been here for a long time!'); } /*]]>*/ </script> Thymeleaf 2.1
... ]]> in <script> or <style> 1. New Template Mode <script> var user = ... if (user.signupYear < 1990) { alert('You\'ve been here for a long time!'); } </script> Thymeleaf 3.0
Output values without a supporting tag • Already existed th:inline=“text" in Thymeleaf 2.1 • Now a 1st-class citizen, no th:inline needed • In fact, better remove them <p> This is called [[${product.name}]] and it's great! </p>
th:inline="text"> This is called [[${product.name}]] and it's great! </p> <p> This is called [[${product.name}]] and it's great! </p> Thymeleaf 2.1 Thymeleaf 3.0
1. New Template Mode <p> This is called <th:block th:text="${product.name}"/> and it's great! </p> <p> This is called [[${product.name}]] and it's great! </p>
parse “[[…]]”, you can set th:inline=“none”: 1. New Template Mode <p th:inline="none"> The expression for showing the product name is "[[$ {product.name}]]" and it's very simple. </p>
Mode Dear [(${customer.name})], This is the list of our products: [# th:each="prod : ${products}"] - [(${prod.name})]. Price: [(${prod.price})] EUR/kg [/] Thanks, The Thymeleaf Shop
Mode Dear [(${customer.name})], This is the list of our products: [#th:block th:each="prod : ${products}"] - [(${prod.name})]. Price: [(${prod.price})] EUR/kg [/th:block] Thanks, The Thymeleaf Shop
Mode Dear [# th:utext="${customer.name}" /], This is the list of our products: [#th:block th:each="prod : ${products}"] - [(${prod.name})]. Price: [(${prod.price})] EUR/kg [/th:block] Thanks, The Thymeleaf Shop
Mode Dear [#th:block th:utext="${customer.name}" /], This is the list of our products: [#th:block th:each="prod : ${products}"] - [(${prod.name})]. Price: [(${prod.price})] EUR/kg [/th:block] Thanks, The Thymeleaf Shop
Mode Dear [(${customer.name})], This is the list of our products: [# th:each="prod : ${products}"] - [(${prod.name})]. Price: [(${prod.price})] EUR/kg [/] Thanks, The Thymeleaf Shop
• Expression result: underscore(‘_') • Use prototyping text as default values 3. No-Operation Token <span th:text="${user.name} ?: _">no user authenticated</span>
2.1 for non-web applications • Non-ServletAPI webs had unsolved needs • Non-absolute URL handling, context integration /* Customize the way URLs are handled: context, rewriting, etc. */ tempEngine.setLinkBuilder(new ILinkBuilder() {...}); /* Customize the way context variables are maintained */ tempEngine.setEngineContextFactory(new IEngineContextFactory() {...});
check Thymeleaf Standard Dialect, you can write codes like this: @Test public void test() { TemplateEngine engine = new TemplateEngine(); Context context = new Context(); context.setVariable("name", "Mitsuyuki"); String result = engine.process( "I'm [[${name}]].", context); assertThat(result, is("I'm Mitsuyuki.")); }
you use Spring, you should use SpringStandardDialect.: @Test public void test() { TemplateEngine engine = new TemplateEngine(); engine.setDialect(new SpringStandardDialect()); Context context = new Context(); context.setVariable("name", "Mitsuyuki"); String result = engine.process( "I'm [[${name}]].", context); assertThat(result, is("I'm Mitsuyuki.")); }
you use Spring, you should use SpringStandardDialect.: @Test public void test() { TemplateEngine engine = new TemplateEngine(); engine.setDialect(new SpringStandardDialect()); Context context = new Context(); context.setVariable("name", "Mitsuyuki"); String result = engine.process( "I'm [[${name}]].", context); assertThat(result, is("I'm Mitsuyuki.")); }
change for migrating from Thymeleaf 2.1 to 3.0. • On the other hand, inside was changed so much that you can get the performance improvement. • So why don’t you use Thymeleaf 3.0? Thank you!
Thymeleaf by Daniel Fernández https://youtu.be/GVq0uzpHYoQ • The Thymeleaf Artwork by The Thymeleaf Project is licensed under the Creative Commons CC BY-SA 3.0 License.