Se ha denunciado esta presentación.
Se está descargando tu SlideShare. ×

Lessons learned from upgrading Thymeleaf

Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Próximo SlideShare
Working with Servlets
Working with Servlets
Cargando en…3
×

Eche un vistazo a continuación

1 de 33 Anuncio

Lessons learned from upgrading Thymeleaf

Descargar para leer sin conexión

SpringOne Platform 2017
Jay Aisenbrey, Thymeleaf

Thymeleaf 3 has introduced new features such as the ability to decouple templating logic from the HTML, better performance, not being XML-based, and the addition of template fragments as a first class citizen. This talk will cover what you need to know to upgrade your application from Thymeleaf 2 to 3 along with what to watch out for in the process.

SpringOne Platform 2017
Jay Aisenbrey, Thymeleaf

Thymeleaf 3 has introduced new features such as the ability to decouple templating logic from the HTML, better performance, not being XML-based, and the addition of template fragments as a first class citizen. This talk will cover what you need to know to upgrade your application from Thymeleaf 2 to 3 along with what to watch out for in the process.

Anuncio
Anuncio

Más Contenido Relacionado

Presentaciones para usted (20)

Similares a Lessons learned from upgrading Thymeleaf (20)

Anuncio

Más de VMware Tanzu (20)

Más reciente (20)

Anuncio

Lessons learned from upgrading Thymeleaf

  1. 1. Lessons Learned from Upgrading Thymeleaf By Jay Aisenbrey @broadleaf 1
  2. 2. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Broadleaf Commerce • Open source, Spring-based eCommerce framework • Enterprise features • Order Management System • Content Management System • Multi-Tenant Single Schema • Fortune 500 and IR Top 100 clients • The Container Store • The Buckle • O'Reilly Auto Parts • Customizable, flexible, and scalable 2
  3. 3. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf • Open source server-side Java template engine • Write pure HTML, CSS, and JS that can be displayed without processing • Built-in Spring integrations • Uses SpEL and OGNL • Therefore you can use static class and object functions • Full internationalization support • Highly customizable • Configurable parsed template cache • Cache where the template is and, possibly, what it evaluates to 3
  4. 4. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf 3 Features - Fragments The old fragment expressions but expanded on • Not only limited to use inside th:insert/th:replace/th:include • <div th:include="home :: home_fragment"></div> • <div th:include="~{home :: home_fragment}"></div> • Same syntax as before i.e. ~{home :: home_fragment} • Now available for use everywhere ${...}, *{...}, etc. can be used • Use with th:with to use templates as variables or in an conditional • Using fragments as parameters in other fragments 4
  5. 5. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Fragments - Examples ~{commons::main} <div th:insert="~{commons :: main}">...</div> <div th:insert="${user.admin}? ~{adm :: admintools} : ~{common :: basictools}">...</div> <div th:with="frag=~{footer :: #main/text()}"> <p th:insert="${frag}"> </div> 5
  6. 6. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Fragments - Examples (base.html) <head th:fragment="common_header(title,links)"> <title th:replace="${title}">The awesome application</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}"> <link rel="shortcut icon" th:href="@{/images/favicon.ico}"> <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"/> <!--/* Per-page placeholder for additional links */--> <th:block th:replace="${links}" /> </head> 6
  7. 7. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Fragments - Examples (main.html) ... <head th:replace="base :: common_header(~{::title},~{::link})"> <title>Awesome - Main</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> </head> ... 7
  8. 8. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Fragments - Examples (resulting main.html) ... <head> <title>Awesome - Main</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}"> <link rel="shortcut icon" th:href="@{/images/favicon.ico}"> <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"/> <!--/* Per-page placeholder for additional links */--> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> </head> ... 8
  9. 9. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf 3 Features - Decoupled Templating ... <table id="usersTable"> <tr th:each="user : ${users}"> <td class="username" th:text="${user.name}"> Jeremy Grapefruit </td> <td class="usertype" th:text="#{|user.type.${user.type}|}"> Normal User </td> </tr> </table> ... 9
  10. 10. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf 3 Features - Decoupled Templating <!DOCTYPE html> <html> <body> <table id="usersTable"> <tr> <td class="username">Jeremy Grapefruit</td> <td class="usertype">Normal User</td> </tr> <tr> <td class="username">Alice Watermelon</td> <td class="usertype">Administrator</td> </tr> </table> </body> </html> 10
  11. 11. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf 3 Features - Decoupled Templating <?xml version="1.0"?> <thlogic> <attr sel="#usersTable" th:remove="all-but-first"> <attr sel="/tr[0]" th:each="user : ${users}"> <attr sel="td.username" th:text="${user.name}" /> <attr sel="td.usertype" th:text="#{|user.type.${user.type}|}" /> </attr> </attr> </thlogic> 11
  12. 12. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf 3 Features • Inline Expression • <div th:inline="text">[[${user.name}]]</div> --> <div>[[${user.name}]]</div> • Textual Template Mode - Ability to write Thymeleaf syntax without tags [# th:each="item : ${items}"] - [# th:utext="${item}" /] [/] • No longer dependent on Servlet API • Enables Thymeleaf to run outside of a web container (i.e. email templating) • Improves integration possibilities with reactive frameworks • Supports engine throttling so that the Thymeleaf engine can execute partially and on-demand to answer back-pressure requests 12
  13. 13. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thymeleaf 3 Features • Parser change • Originally used an XML parser, now uses an event-driven parser • New parser called Attoparser 2.0 (written by the same guy behind Thymeleaf) • Performance increase • No longer requires HTML to be valid XML (Full HTML5 support) • Small templating caveat • <div th:text="${text}"/> --> if text is empty this results to <div/> • The browser attempts to find a place for the closing div and it's always wrong • In Thymeleaf 2 this would return <div></div> • Simply change to <div th:text="${text}></div> 13
  14. 14. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Variable Expressions - Thymeleaf 2 public class BroadleafVariableExpressionEval extends SpelVariableExpressionEvaluator { @Override protected Map<String,Object> computeAdditionalExpressionObjects( final IProcessingContext processingContext) { // Map expression objects to a string } } 14
  15. 15. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Variable Expressions - Thymeleaf 3 public class BroadleafVariableExpressionObjectFactory implements IExpressionObjectFactory{ @Override public Set<String> getAllExpressionObjectNames() { // Return string names to be used to use variable expressions } @Override public Object buildObject(IExpressionContext context, String expressionObjectName) { // Based on string given return object is relates to } } 15
  16. 16. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Variable Expressions - Difference • Slightly different API but effectively setup the same way • HTML usage remains identical Thymeleaf 2 - https://git.io/vbTIr Thymeleaf 3 - https://git.io/vbTIo Both are capital "i"s following the "T" 16
  17. 17. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Dialects - Thymeleaf 2 public interface IDialect { public String getPrefix(); public Set<IProcessor> getProcessors(); public Map<String,Object> getExecutionAttributes(); public Set<IDocTypeTranslation> getDocTypeTranslations(); public Set<IDocTypeResolutionEntry> getDocTypeResolutionEntries(); } 17
  18. 18. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Dialects - Thymeleaf 3 public abstract class TL3EquivalentDialect extends AbstractProcessorDialect implements IExpressionObjectDialect { public String getName(); public String getPrefix(); public int getDialectProcessorPrecedence(); public Set<IProcessor> getProcessors(final String dialectPrefix); public IExpressionObjectFactory getExpressionObjectFactory(); } 18
  19. 19. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Dialects - Difference • Thymeleaf 3 refactored the API into a more modular way • i.e. IProcessorDialect, IPreProcessorDialect, IPostProcessorDialect, IExpressionObjectDialect, IExecutionAttributeDialect • Replaced getExecutionAttributes with getExpressionObjectFactory • This makes more sense since you're no longer mapping a magic string to an object • Hooking up the dialect to the engine is exactly the same • Again a lot of similarities • Thymeleaf 2 - https://git.io/vbTtM • Thymeleaf 3 - https://git.io/vbTtD 19
  20. 20. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Processors - Thymeleaf 2 public interface IProcessor extends Comparable<IProcessor> { public IProcessorMatcher<? extends Node> getMatcher(); public ProcessorResult process( final Arguments arguments, final ProcessorMatchingContext processMatchContext, final Node node); } • getMatcher - What type of HTML should this be ran on • process - What are we doing on this HTML that matches 20
  21. 21. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Processors - Thymeleaf 2 • AbstractProcessor implements IProcessor • Provides methods to resolve internationalized messages and compareTo • AbstractAttrProcessor extends AbstractProcessor • Implements getMatcher to say this runs on tags with certain attribute name • AbstractElementProcessor • Implements getMatcher to say this runs on tags with certain tag name 21
  22. 22. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Processors - Thymeleaf 3 public interface IProcessor { public TemplateMode getTemplateMode(); // HTML, XML, etc. public int getPrecedence(); } public interface IElementProcessor extends IProcessor { public MatchingElementName getMatchingElementName(); public MatchingAttributeName getMatchingAttributeName(); } 22
  23. 23. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Processors - Thymeleaf 3 public interface IElementTagProcessor extends IElementProcessor { public void process( final ITemplateContext context, final IProcessableElementTag tag, final IElementTagStructureHandler structureHandler); } public interface IElementModelProcessor extends IElementProcessor { public void process( final ITemplateContext context, final IModel model, final IElementModelStructureHandler structureHandler); } 23
  24. 24. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Processors - Thymeleaf 3 Other interfaces (all extend IProcessor) • ITemplateBoundariesProcessor • ITextProcessor • ICommentProcessor • ICDATASectionProcessor • IDocTypeProcessor • IXMLDeclarationProcessor All have their own StructureHandlers 24
  25. 25. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Processors - Differences Thymeleaf 2 • getMatcher • Method argument Arguments • Not very defined. Hard to use • Wild west on what you can do inside a processor 25 Thymeleaf 3 • More granular APIs • Method argument StructureHandler • Very detailed API. Easy to use • More structured on what you can do inside a processor based on type
  26. 26. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration - Maven POM <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.9.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> <version>3.0.9.RELEASE</version> </dependency> 26
  27. 27. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration - Spring Java Config @Configuration @EnableWebMvc public class ThymeleafConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Bean public ViewResolver viewResolver() { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine()); resolver.setCharacterEncoding("UTF-8"); return resolver; } ... 27
  28. 28. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration - Spring Java Config ... @Bean public TemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setEnableSpringELCompiler(true); engine.setTemplateResolver(templateResolver()); return engine; } private ITemplateResolver templateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(applicationContext); resolver.setPrefix("/WEB-INF/templates/"); resolver.setTemplateMode(TemplateMode.HTML); return resolver; } } 28
  29. 29. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Summary • Not a lot to upgrading unless you have lots of processors • Even then the new API is much simpler • New features • Better fragment expressions • Decoupled templating • Increased performance • No more XML parser • New sleeker APIs for Variable Expressions, Dialects, Processors • Addition of pre/post processors 29
  30. 30. Resources • Migration Guide • http://www.thymeleaf.org/doc/articles/thymeleaf3migration.html • Extension Guide • http://www.thymeleaf.org/doc/tutorials/3.0/extendingthymeleaf.html • My Blog • http://www.broadleafcommerce.com/blog/broadleaf-commerce-upgrade-to- thymeleaf-3 • Introduction to Thymeleaf Presentation • http://www.nimret.org/seajug/past/2016/oct/slides.pdf
  31. 31. Q&A
  32. 32. Learn More. Stay Connected. jaisenbrey@broadleafcommerce.com Github: cja769 Twitter: @broadleaf 32 #springone@s1p

×