Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Welcome Thymeleaf 3.0! #jjug_ccc #ccc_f2

Welcome Thymeleaf 3.0! #jjug_ccc #ccc_f2

Mitsuyuki Shiiba

May 21, 2016
Tweet

More Decks by Mitsuyuki Shiiba

Other Decks in Technology

Transcript

  1. #jjug_ccc #ccc_f2
    @bufferings
    Welcome Thymeleaf 3.0!
    2016-05-21 JJUG CCC 2016 Spring
    Mitsuyuki Shiiba

    View Slide

  2. #jjug_ccc #ccc_f2
    @bufferings
    http://www.thymeleaf.org/

    View Slide

  3. #jjug_ccc #ccc_f2
    @bufferings
    http://www.thymeleaf.org/
    Have you ever used it?

    View Slide

  4. #jjug_ccc #ccc_f2
    @bufferings
    Finally released on 2016-05-08!
    Welcome Thymeleaf 3.0!
    http://www.thymeleaf.org/

    View Slide

  5. #jjug_ccc #ccc_f2
    @bufferings
    Agenda
    • Part1: Introducing Thymeleaf
    • Part2: What’s new in Thymeleaf 3.0?

    View Slide

  6. #jjug_ccc #ccc_f2
    @bufferings
    Your tweets are welcomed!
    HashTag: #ccc_f2

    View Slide

  7. #jjug_ccc #ccc_f2
    @bufferings
    • twitter: @bufferings
    • Java WebApp Engineer
    • #kanjava #devkan #kandddj
    Mitsuyuki Shiiba

    View Slide

  8. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf (ja)
    Mitsuyuki Shiiba
    http://www.thymeleaf.org/documentation.html

    View Slide

  9. #jjug_ccc #ccc_f2
    @bufferings
    Special thanks to Daniel Fernández, who is 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.

    View Slide

  10. #jjug_ccc #ccc_f2
    @bufferings
    Part1: Introducing Thymeleaf

    View Slide

  11. #jjug_ccc #ccc_f2
    @bufferings
    Part1: Introducing Thymeleaf
    • What is Thymeleaf?
    • Getting Started
    • Using Thymeleaf
    • My Tips

    View Slide

  12. #jjug_ccc #ccc_f2
    @bufferings
    What is Thymeleaf?
    • A template engine 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

    View Slide

  13. #jjug_ccc #ccc_f2
    @bufferings
    What does it look like?
    What is Thymeleaf?


    Name
    Price



    Oranges
    0.99



    View Slide

  14. #jjug_ccc #ccc_f2
    @bufferings
    to solve the design-development roundtrip issue
    Why was it started?
    What is Thymeleaf?

    View Slide

  15. #jjug_ccc #ccc_f2
    @bufferings
    “the template can be a document as 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

    View Slide

  16. #jjug_ccc #ccc_f2
    @bufferings
    Natural Templates
    What is Thymeleaf?
    http://www.thymeleaf.org/doc/articles/petclinic.html
    Statically Opened WebApp Output

    View Slide

  17. #jjug_ccc #ccc_f2
    @bufferings
    Natural Templates
    What is Thymeleaf?

    View Slide

  18. #jjug_ccc #ccc_f2
    @bufferings
    The trick
    What is Thymeleaf?
    • Use non-standard attributes

    th:text="${f.name}">Apricot

    • Browsers ignore them

    View Slide

  19. #jjug_ccc #ccc_f2
    @bufferings
    HTML5 allows custom attributes
    What is Thymeleaf?

    data-th-text="${f.name}">Apricot


    Apricot

    browser display equivalent

    View Slide

  20. #jjug_ccc #ccc_f2
    @bufferings
    Now we can prototype!
    What is Thymeleaf?
    th:src="@{/images/logo.png}" />


    browser display equivalent
    output of running webapp

    View Slide

  21. #jjug_ccc #ccc_f2
    @bufferings
    Yet prototyping is very optional
    What is Thymeleaf?
    • No need for double attributes:
    • src + th:src, href + th:href
    • No need for prototyping text
    • Expressions can be inlined


    Welcome to our e-shop, [[${session.user.name}]].
    td>

    View Slide

  22. #jjug_ccc #ccc_f2
    @bufferings
    Part1: Introducing Thymeleaf
    • What is Thymeleaf?
    • Getting Started
    • Using Thymeleaf
    • My Tips

    View Slide

  23. #jjug_ccc #ccc_f2
    @bufferings
    Getting Started
    Spring Boot is one of the easiest options.

    View Slide

  24. #jjug_ccc #ccc_f2
    @bufferings
    Step1. SPRING INITIALIZR
    Open http://start.spring.io/
    Getting Started

    View Slide

  25. #jjug_ccc #ccc_f2
    @bufferings
    Step1. SPRING INITIALIZR
    Select Thymeleaf in dependencies box
    Getting Started

    View Slide

  26. #jjug_ccc #ccc_f2
    @bufferings
    Step1. SPRING INITIALIZR
    Click “Generate Project”
    Getting Started

    View Slide

  27. #jjug_ccc #ccc_f2
    @bufferings
    Step1. SPRING INITIALIZR
    Then you can get a project zip file
    Getting Started

    View Slide

  28. #jjug_ccc #ccc_f2
    @bufferings
    Step2. Create Template File
    src/main/resources/templates/greeting.html
    Getting Started



    Greeting Demo


    Hello World


    View Slide

  29. #jjug_ccc #ccc_f2
    @bufferings
    Step2. Create Template File
    src/main/resources/templates/greeting.html
    Getting Started

    View Slide

  30. #jjug_ccc #ccc_f2
    @bufferings
    Step3. Create Controller
    src/main/java/com/example/GreetingController.java
    Getting Started
    @Controller
    public class GreetingController {
    @RequestMapping("/")
    public String hello(Model model) {
    model.addAttribute("name", "Mitsuyuki");
    return "greeting";
    }
    }

    View Slide

  31. #jjug_ccc #ccc_f2
    @bufferings
    Step4. Run
    $ ./mvnw spring-boot:run
    Getting Started

    View Slide

  32. #jjug_ccc #ccc_f2
    @bufferings
    Now we have Thymeleaf!
    Getting Started

    View Slide

  33. #jjug_ccc #ccc_f2
    @bufferings
    +1. Disable Cache(for DEV)
    Getting Started
    src/main/resources/application.yml
    spring:
    thymeleaf:
    cache: false

    View Slide

  34. #jjug_ccc #ccc_f2
    @bufferings
    +1. Disable Cache(for DEV)
    Getting Started
    src/main/resources/application.yml
    spring:
    thymeleaf:
    cache: false
    or

    org.springframework.boot
    spring-boot-devtools
    true

    View Slide

  35. #jjug_ccc #ccc_f2
    @bufferings
    JerseyMVC?
    Getting Started
    If you are interested in using Thymeleaf with
    JerseyMVC, let’s join #ccc_cd4 Tada-san’s session!

    View Slide

  36. #jjug_ccc #ccc_f2
    @bufferings
    Part1: Introducing Thymeleaf
    • What is Thymeleaf?
    • Getting Started
    • Using Thymeleaf
    • My Tips

    View Slide

  37. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf
    James Carrot

    View Slide

  38. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf
    James Carrot
    Expression

    View Slide

  39. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf
    James Carrot
    Processor Expression

    View Slide

  40. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf
    James Carrot
    Processor Expression
    + + etc… = Dialect

    View Slide

  41. #jjug_ccc #ccc_f2
    @bufferings
    Standard Dialect
    Using Thymeleaf
    The out-of-the-box dialect in Thymeleaf
    • Standard Expressions
    • Standard Processors
    • etc…
    James Carrot

    View Slide

  42. #jjug_ccc #ccc_f2
    @bufferings
    Standard Dialect
    Using Thymeleaf
    The out-of-the-box dialect in Thymeleaf
    • Standard Expressions
    • Standard Processors
    • etc…
    James Carrot

    View Slide

  43. #jjug_ccc #ccc_f2
    @bufferings
    Standard Expressions
    Using Thymeleaf
    1. Simple Expressions
    2. Expression Objects
    3. Literals
    4. Operators

    View Slide

  44. #jjug_ccc #ccc_f2
    @bufferings
    1. Simple Expressions
    Standard Expressions
    • Variable Expression: ${...}, *{...}
    • Link Expression: @{...}
    • Message Expression: #{...}
    • Fragment Expression: ~{...}
    James Carrot

    View Slide

  45. #jjug_ccc #ccc_f2
    @bufferings
    2. Expression Objects
    Standard Expressions
    • #ctx, #vars, #root, #locale, #object
    • #request, #session,

    #response, #servletContext
    • #conversions, #uris
    US

    View Slide

  46. #jjug_ccc #ccc_f2
    @bufferings
    2. Expression Objects
    Standard Expressions
    • #calendars, #dates, #bools, #numbers, #objects,
    #strings, #arrays, #lists, #sets, #maps,
    #aggregates, #messages, #ids, #execInfo
    13 May 2011

    View Slide

  47. #jjug_ccc #ccc_f2
    @bufferings
    3. Literals(Tokens)
    Standard Expressions
    • Text: ‘Good Morning!’,’Hello’ + ‘World’
    • Number: 2016, 2020 - 4, 3.14
    • Boolean: true, false
    • Null: null
    • NO-OP: _
    ...

    View Slide

  48. #jjug_ccc #ccc_f2
    @bufferings
    4. Operators
    Standard Expressions
    • +, -, *, /, div, %, mod
    • and, or, not, !
    • ==, eq, !=, neq, ne
    • >, >=, • A ? B : C, A ?: C
    th:with="isEven=(${prodStat.count} % 2 == 0)"

    View Slide

  49. #jjug_ccc #ccc_f2
    @bufferings
    Standard Dialect
    Using Thymeleaf
    The out-of-the-box dialect in Thymeleaf
    • Standard Expressions
    • Standard Processors
    • etc…
    James Carrot

    View Slide

  50. #jjug_ccc #ccc_f2
    @bufferings
    Standard Processors
    Using Thymeleaf
    1. th:text
    2. th:attr
    3. th:if
    4. th:remove
    5. th:each
    6. Comments and Blocks
    etc…

    View Slide

  51. #jjug_ccc #ccc_f2
    @bufferings
    1. th:text
    Standard Processors
    James Carrot

    View Slide

  52. #jjug_ccc #ccc_f2
    @bufferings
    1. th:text
    Standard Processors
    James Carrot
    Mitsuyuki Shiiba
    output of running webapp

    View Slide

  53. #jjug_ccc #ccc_f2
    @bufferings
    1. th:text
    Standard Processors
    • , &, " and ‘ will be escaped (in Html mode)
    • Unescaped processor is “th:utext”
    James Carrot
    HtmlEscape.escapeHtml4Xml(unbescape) http://goo.gl/MDQr8E
    Mitsuyuki Shiiba
    output of running webapp

    View Slide

  54. #jjug_ccc #ccc_f2
    @bufferings
    1. th:text
    Standard Processors

    View Slide

  55. #jjug_ccc #ccc_f2
    @bufferings
    1. th:text
    Standard Processors

    Hello Mitsuyuki Shiiba!
    output of running webapp

    View Slide

  56. #jjug_ccc #ccc_f2
    @bufferings
    2. th:attr
    Standard Processors
    100

    View Slide

  57. #jjug_ccc #ccc_f2
    @bufferings
    2. th:attr
    Standard Processors
    100
    100
    output of running webapp
    • , &, " and ‘ will be escaped

    View Slide

  58. #jjug_ccc #ccc_f2
    @bufferings
    2. th:attr
    Standard Processors
    100
    th:* attributes

    th:href="@{/product/comments(prodId=${prod.id})}"
    >view

    View Slide

  59. #jjug_ccc #ccc_f2
    @bufferings
    3. th:if
    Standard Processors
    th:href="@{/product/comments(prodId=${prod.id})}"
    th:if="${not #lists.isEmpty(prod.comments)}"
    >view

    View Slide

  60. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors

    First
    Second

    View Slide

  61. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors

    First
    Second

    output of running webapp

    View Slide

  62. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors
    • all
    • all-but-first
    • tag(tags)
    • body
    • none

    View Slide

  63. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors

    First
    Second

    th:remove=“all”
    output of running webapp

    View Slide

  64. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors

    First
    Second


    First

    th:remove=“all-but-first”
    output of running webapp

    View Slide

  65. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors

    First
    Second

    First
    Second
    th:remove=“tag”
    output of running webapp

    View Slide

  66. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors

    First
    Second


    th:remove=“body”
    output of running webapp

    View Slide

  67. #jjug_ccc #ccc_f2
    @bufferings
    4. th:remove
    Standard Processors
    th:remove=“none” is for conditional use.
    Link text not to be removed

    View Slide

  68. #jjug_ccc #ccc_f2
    @bufferings
    5. th:each
    Standard Processors

    th:text="${name}">First


    Apple
    Banana
    Cake

    output of running webapp

    View Slide

  69. #jjug_ccc #ccc_f2
    @bufferings
    5. th:each
    Standard Processors
    th:each + th:remove=“all-but-first”

    th:text="${name}">First
    Second
    Third


    Apple
    Banana
    Cake

    output of running webapp

    View Slide

  70. #jjug_ccc #ccc_f2
    @bufferings
    5. th:each
    Standard Processors
    Iteration Status
    th:text="${name} + ${iterStat.count}"
    >First

    View Slide

  71. #jjug_ccc #ccc_f2
    @bufferings
    5. th:each
    Standard Processors
    Iteration Status
    th:text="${name} + ${iterStat.count}"
    >First
    th:text="${name} + ${nameStat.count}"
    >First

    View Slide

  72. #jjug_ccc #ccc_f2
    @bufferings
    5. th:each
    Standard Processors
    Iteration Status
    • index(from 0)
    • count(from 1)
    • size
    • current(current Object)
    • even/odd(boolean/start from 1)
    • first/last(boolean)

    View Slide

  73. #jjug_ccc #ccc_f2
    @bufferings
    6. Comments and Blocks
    Standard Processors
    Parser level comment blocks

    View Slide

  74. #jjug_ccc #ccc_f2
    @bufferings
    6. Comments and Blocks
    Standard Processors
    Parser level comment blocks


    you can see me only before thymeleaf processes me!


    View Slide

  75. #jjug_ccc #ccc_f2
    @bufferings
    6. Comments and Blocks
    Standard Processors
    Parser level comment blocks

    ...

    ...
    ...


    View Slide

  76. #jjug_ccc #ccc_f2
    @bufferings
    6. Comments and Blocks
    Standard Processors
    Prototype-only comment blocks
    hello!

    goodbye!
    hello!

    ...

    goodbye!
    output of running webapp

    View Slide

  77. #jjug_ccc #ccc_f2
    @bufferings
    6. Comments and Blocks
    Standard Processors
    th:block



    ...
    ...


    th:text="${user.address}">...



    View Slide

  78. #jjug_ccc #ccc_f2
    @bufferings
    6. Comments and Blocks
    Standard Processors
    th:block



    ...
    ...


    th:text="${user.address}">...



    View Slide

  79. #jjug_ccc #ccc_f2
    @bufferings
    Part1: Introducing Thymeleaf
    • What is Thymeleaf?
    • Getting Started
    • Using Thymeleaf
    • My Tips

    View Slide

  80. #jjug_ccc #ccc_f2
    @bufferings
    My Tips
    • Keep natural templating
    • otherwise it would be stale soon

    View Slide

  81. #jjug_ccc #ccc_f2
    @bufferings
    My Tips
    • Keep natural templating
    • otherwise it would be stale soon
    • Keep template simple
    • no tricky template
    • no logics in template
    • no mix of html and javascript

    View Slide

  82. #jjug_ccc #ccc_f2
    @bufferings
    Part1: Introducing Thymeleaf
    • What is Thymeleaf?
    • Getting Started
    • Using Thymeleaf
    • My Tips

    View Slide

  83. #jjug_ccc #ccc_f2
    @bufferings
    Part2: What’s new in Thymeleaf 3.0?

    View Slide

  84. #jjug_ccc #ccc_f2
    @bufferings
    Part2: What’s new in Thymeleaf 3.0?
    • What is Thymeleaf 3.0?
    • Migration Guide
    • Using Thymeleaf 3.0
    • Summary

    View Slide

  85. #jjug_ccc #ccc_f2
    @bufferings
    What is Thymeleaf 3.0?
    • Dev of 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

    View Slide

  86. #jjug_ccc #ccc_f2
    @bufferings
    A new architecture

    View Slide

  87. #jjug_ccc #ccc_f2
    @bufferings
    Improved performance

    View Slide

  88. #jjug_ccc #ccc_f2
    @bufferings
    Full HTML5 Support
    • New parsing system
    • No longer XML-based
    • Created from scratch with Thymeleaf in mind
    Whatever
    valid template!
    http://www.attoparser.org/

    View Slide

  89. #jjug_ccc #ccc_f2
    @bufferings
    TEXT 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

    View Slide

  90. #jjug_ccc #ccc_f2
    @bufferings
    Part2: What’s new in Thymeleaf 3.0?
    • What is Thymeleaf 3.0?
    • Migration Guide
    • Using Thymeleaf 3.0
    • Summary

    View Slide

  91. #jjug_ccc #ccc_f2
    @bufferings
    Migration Guide
    • Templates
    • almost 100% compatible
    • (It is recommended to delete th:inline=“text”)
    • Configuration
    • a few modifications are needed

    View Slide

  92. #jjug_ccc #ccc_f2
    @bufferings
    Migration Guide
    Configuration change for Spring Boot 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

    View Slide

  93. #jjug_ccc #ccc_f2
    @bufferings
    Step1. Modify pom.xml
    Add repository
    https://github.com/bufferings/thymeleaf3-spring-boot
    Migration Guide

    bufferings
    https://raw.github.com/bufferings/thymeleaf3-
    spring-boot/mvn-repo/

    View Slide

  94. #jjug_ccc #ccc_f2
    @bufferings
    Step1. Modify pom.xml
    Replace dependency
    https://github.com/bufferings/thymeleaf3-spring-boot
    Migration Guide

    jp.gr.java_conf.bufferings
    thymeleaf3-spring-boot
    0.0.1

    View Slide

  95. #jjug_ccc #ccc_f2
    @bufferings
    Step1. Modify pom.xml
    Override “thymeleaf.version” of parent
    https://github.com/bufferings/thymeleaf3-spring-boot
    Migration Guide
    3.0.0.RELEASE

    View Slide

  96. #jjug_ccc #ccc_f2
    @bufferings
    Step2. Add an exclude parameter
    To exclude default ThymeleafAutoConfiguration
    https://github.com/bufferings/thymeleaf3-spring-boot
    Migration Guide
    @SpringBootApplication(
    exclude = ThymeleafAutoConfiguration.class)
    public class DemoApplication {

    View Slide

  97. #jjug_ccc #ccc_f2
    @bufferings
    Migration Guide
    Configuration change for those who create
    TemplateEngine class by yourself.
    private TemplateEngine templateEngine() {
    ServletContextTemplateResolver resolver =
    new ServletContextTemplateResolver();
    resolver.setPrefix("/WEB-INF/templates/");
    resolver.setTemplateMode("HTML5");
    TemplateEngine templateEngine =
    new TemplateEngine();
    templateEngine.setTemplateResolver(resolver);
    return templateEngine;
    }
    Thymeleaf 2.1

    View Slide

  98. #jjug_ccc #ccc_f2
    @bufferings
    Migration Guide
    Configuration change for those who create
    TemplateEngine class by yourself.
    private TemplateEngine templateEngine() {
    ServletContextTemplateResolver resolver =
    new ServletContextTemplateResolver(servletContext);
    resolver.setPrefix("/WEB-INF/templates/");
    resolver.setTemplateMode(TemplateMode.HTML);
    TemplateEngine templateEngine =
    new TemplateEngine();
    templateEngine.setTemplateResolver(resolver);
    return templateEngine;
    }
    Thymeleaf 3.0

    View Slide

  99. #jjug_ccc #ccc_f2
    @bufferings
    Notes for Migration
    Migration Guide
    • Please 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

    View Slide

  100. #jjug_ccc #ccc_f2
    @bufferings
    Part2: What’s new in Thymeleaf 3.0?
    • What is Thymeleaf 3.0?
    • Migration Guide
    • Using Thymeleaf 3.0
    • Summary

    View Slide

  101. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  102. #jjug_ccc #ccc_f2
    @bufferings
    1. New Template Mode
    TemplateMode enum class is introduced
    • HTML, XML
    • TEXT, JAVASCRIPT, CSS
    • RAW

    View Slide

  103. #jjug_ccc #ccc_f2
    @bufferings
    1. New Template Mode
    Old modes are deprecated
    • HTML5, LEGACYHTML5, XHTML, VALIDXHTML

    -> HTML
    • VALIDXML

    -> XML

    View Slide

  104. #jjug_ccc #ccc_f2
    @bufferings
    HTML Mode
    • From Java SAX parser(+nekoHTML) to AttoParser
    • AttoParser is an event-based parser with
    Thymeleaf in mind
    1. New Template Mode
    http://www.attoparser.org/

    View Slide

  105. #jjug_ccc #ccc_f2
    @bufferings
    HTML Mode
    • Full support of both XML and HTML5 (non XML-ized)
    markup
    1. New Template Mode
    Whatever
    valid template!

    View Slide

  106. #jjug_ccc #ccc_f2
    @bufferings
    HTML Mode
    • Validataion enabled parsing no longer exist in
    Thymeleaf 3.0
    1. New Template Mode

    View Slide

  107. #jjug_ccc #ccc_f2
    @bufferings
    HTML Mode
    • No need for in or <style><br/>1. New Template Mode<br/><script><br/>/*<![CDATA[*/<br/>var user = ...<br/>if (user.signupYear < 1990) {<br/>alert('You\'ve been here for a long time!');<br/>}<br/>/*]]>*/<br/>
    Thymeleaf 2.1

    View Slide

  108. #jjug_ccc #ccc_f2
    @bufferings
    HTML Mode
    • No need for in or <style><br/>1. New Template Mode<br/><script><br/>var user = ...<br/>if (user.signupYear < 1990) {<br/>alert('You\'ve been here for a long time!');<br/>}<br/>
    Thymeleaf 3.0

    View Slide

  109. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    1. New Template Mode
    • 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

    This is called [[${product.name}]] and it's great!

    View Slide

  110. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    1. New Template Mode

    This is called [[${product.name}]] and it's great!


    This is called [[${product.name}]] and it's great!

    Thymeleaf 2.1
    Thymeleaf 3.0

    View Slide

  111. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    Underneath, the template mode is used for default
    inline mode:
    1. New Template Mode

    This is called [[${product.name}]] and it's great!

    View Slide

  112. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    Replaced at parsing time with:
    1. New Template Mode

    This is called
    and it's great!


    This is called [[${product.name}]] and it's great!

    View Slide

  113. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    When you don’t want to parse “[[…]]”, you can set
    th:inline=“none”:
    1. New Template Mode

    The expression for showing the product name is "[[$
    {product.name}]]" and it's very simple.

    View Slide

  114. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    For unescaped output, you can use “[(…)]”
    1. New Template Mode
    Description: [(${description})]

    View Slide

  115. #jjug_ccc #ccc_f2
    @bufferings
    Improved Inlining
    For unescaped output, you can use “[(…)]”
    1. New Template Mode
    Description: [(${description})]
    Description:
    p>

    View Slide

  116. #jjug_ccc #ccc_f2
    @bufferings
    TEXT Mode(and JAVASCRIPT, CSS)
    1. New Template 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

    View Slide

  117. #jjug_ccc #ccc_f2
    @bufferings
    TEXT Mode(and JAVASCRIPT, CSS)
    1. New Template 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

    View Slide

  118. #jjug_ccc #ccc_f2
    @bufferings
    TEXT Mode(and JAVASCRIPT, CSS)
    1. New Template 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

    View Slide

  119. #jjug_ccc #ccc_f2
    @bufferings
    TEXT Mode(and JAVASCRIPT, CSS)
    1. New Template 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

    View Slide

  120. #jjug_ccc #ccc_f2
    @bufferings
    TEXT Mode(and JAVASCRIPT, CSS)
    1. New Template 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

    View Slide

  121. #jjug_ccc #ccc_f2
    @bufferings
    JavaScript natural templates
    1. New Template Mode
    var greeter = function() {
    var username = /*[[${user.name}]]*/ 'John Apricot';
    alert('Hello ' + username);
    };
    var greeter = function() {
    var username ='Martin Grapefruit';
    alert('Hello ' + username);
    };
    both and .js files<br/>processing result<br/>

    View Slide

  122. #jjug_ccc #ccc_f2
    @bufferings
    RAW Mode
    1. New Template Mode
    Mainly for inserting untouched resources (files, URL
    responses, etc.) into the templates being processed.

    View Slide

  123. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  124. #jjug_ccc #ccc_f2
    @bufferings
    2. Fragment Expressions
    In Standard Dialect
    • Template Layout(existing in Themeleaf 2.1)
    • Fragment Expressions(from Thymeleaf 3.0)

    View Slide

  125. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace

    View Slide

  126. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace
    • Define a template fragment with “th:fragment”

    View Slide

  127. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace
    • Define a template fragment with “th:fragment”



    © 2011 The Good Thymes Virtual Grocery



    include.html

    View Slide

  128. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace
    • Include it with “th:replace”

    ...


    View Slide

  129. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace
    • Include it with “th:replace”

    ...

    © 2011 The Good Thymes Virtual Grocery


    processing result

    View Slide

  130. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace
    • Include it with “th:replace”

    View Slide

  131. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment + th:replace
    • Include it with “th:replace”

    Template Name Fragment Name

    View Slide

  132. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    You can write like this:

    View Slide

  133. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    You can specify fragment without “th:fragment” using
    DOM selector:
    ...

    View Slide

  134. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment can define parameters:

    ...

    ...

    View Slide

  135. #jjug_ccc #ccc_f2
    @bufferings
    Template Layout
    2. Fragment Expressions
    th:fragment can define parameters:

    ...

    ...
    And Thymeleaf 3.0 has Fragment Expressions.

    View Slide

  136. #jjug_ccc #ccc_f2
    @bufferings
    Fragment Expressions: ~{...}
    Generalised syntax of th:insert, th:replace


    Thymeleaf 2.1
    Thymeleaf 3.0
    Please don’t worry. The older syntax still works.
    2. Fragment Expressions

    View Slide

  137. #jjug_ccc #ccc_f2
    @bufferings
    Fragment Expressions: ~{...}
    Can be used elsewhere... even as parameters!

    Awesome - Main
    th:href="@{/css/bootstrap.min.css}">
    th:href="@{/themes/smoothness/jquery-ui.css}">

    2. Fragment Expressions

    View Slide

  138. #jjug_ccc #ccc_f2
    @bufferings
    Fragment Expressions: ~{...}
    Can be used elsewhere... even as parameters!

    The awesome app





    2. Fragment Expressions
    base.html

    View Slide

  139. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  140. #jjug_ccc #ccc_f2
    @bufferings
    • Ability for processors to do nothing
    • Expression result: underscore(‘_')
    • Use prototyping text as default values
    3. No-Operation Token
    no user
    authenticated

    View Slide

  141. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  142. #jjug_ccc #ccc_f2
    @bufferings
    4. Decoupled Templates


    Green Plum
    Round-oval shape


    fruits.html






    fruits.th.xml

    View Slide

  143. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  144. #jjug_ccc #ccc_f2
    @bufferings
    Independence From Servlet API
    • Already in 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() {...});

    View Slide

  145. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  146. #jjug_ccc #ccc_f2
    @bufferings
    6. Reactive Friendliness
    • Sorry, I will study spring reactive!
    • If you are interested in, please check this repo:

    https://github.com/thymeleaf/thymeleafsandbox-
    springreactive

    View Slide

  147. #jjug_ccc #ccc_f2
    @bufferings
    Using Thymeleaf 3.0
    1. New Template Mode
    2. Fragment Expressions
    3. No-Operation Token
    4. Decoupled Templates
    5. Independence From Servlet API
    6. Reactive Friendliness
    7. StringTemplateResolver

    View Slide

  148. #jjug_ccc #ccc_f2
    @bufferings
    7. StringTemplateResolver
    • If you want to 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."));
    }

    View Slide

  149. #jjug_ccc #ccc_f2
    @bufferings
    7. StringTemplateResolver
    • Please note that if 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."));
    }

    View Slide

  150. #jjug_ccc #ccc_f2
    @bufferings
    7. StringTemplateResolver
    • Please note that if 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."));
    }

    View Slide

  151. #jjug_ccc #ccc_f2
    @bufferings
    7. StringTemplateResolver
    • StringTemplateResolver will consider the template
    being resolved as the template itself.
    • This is the default template resolver of
    TemplateEngine.

    View Slide

  152. #jjug_ccc #ccc_f2
    @bufferings
    Part2: What’s new in Thymeleaf 3.0?
    • What is Thymeleaf 3.0?
    • Migration Guide
    • Using Thymeleaf 3.0
    • Summary

    View Slide

  153. #jjug_ccc #ccc_f2
    @bufferings
    Summary
    • You don’t need any big 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!

    View Slide

  154. #jjug_ccc #ccc_f2
    @bufferings
    Reference
    • Thymeleaf Web Site

    http://www.thymeleaf.org/
    • 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.

    View Slide