SlideShare una empresa de Scribd logo
1 de 32
Descargar para leer sin conexión
Lessons Learned from Upgrading
Thymeleaf
By Jay Aisenbrey
@broadleaf
1
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Q&A
Learn More. Stay Connected.
jaisenbrey@broadleafcommerce.com
Github: cja769
Twitter: @broadleaf
32
#springone@s1p

Más contenido relacionado

La actualidad más candente

Lab 5a) create a struts application
Lab 5a) create a struts applicationLab 5a) create a struts application
Lab 5a) create a struts application
techbed
 
3) web development
3) web development3) web development
3) web development
techbed
 

La actualidad más candente (20)

Java EE 6 & Spring: A Lover's Quarrel
Java EE 6 & Spring: A Lover's QuarrelJava EE 6 & Spring: A Lover's Quarrel
Java EE 6 & Spring: A Lover's Quarrel
 
Deepak khetawat sling_models_sightly_jsp
Deepak khetawat sling_models_sightly_jspDeepak khetawat sling_models_sightly_jsp
Deepak khetawat sling_models_sightly_jsp
 
Overview of JEE Technology
Overview of JEE TechnologyOverview of JEE Technology
Overview of JEE Technology
 
OrchardCMS module development
OrchardCMS module developmentOrchardCMS module development
OrchardCMS module development
 
Spring Framework - III
Spring Framework - IIISpring Framework - III
Spring Framework - III
 
Spring Framework -I
Spring Framework -ISpring Framework -I
Spring Framework -I
 
.NET Core, ASP.NET Core Course, Session 10
.NET Core, ASP.NET Core Course, Session 10.NET Core, ASP.NET Core Course, Session 10
.NET Core, ASP.NET Core Course, Session 10
 
Boston 2011 OTN Developer Days - Java EE 6
Boston 2011 OTN Developer Days - Java EE 6Boston 2011 OTN Developer Days - Java EE 6
Boston 2011 OTN Developer Days - Java EE 6
 
jQuery plugins & JSON
jQuery plugins & JSONjQuery plugins & JSON
jQuery plugins & JSON
 
Mvc by asp.net development company in india - part 2
Mvc by asp.net development company in india  - part 2Mvc by asp.net development company in india  - part 2
Mvc by asp.net development company in india - part 2
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
 
Lab 5a) create a struts application
Lab 5a) create a struts applicationLab 5a) create a struts application
Lab 5a) create a struts application
 
Spring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsSpring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topics
 
3) web development
3) web development3) web development
3) web development
 
Hibernate III
Hibernate IIIHibernate III
Hibernate III
 
Spring jdbc
Spring jdbcSpring jdbc
Spring jdbc
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
.NET Core, ASP.NET Core Course, Session 11
.NET Core, ASP.NET Core Course, Session 11.NET Core, ASP.NET Core Course, Session 11
.NET Core, ASP.NET Core Course, Session 11
 
Annotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCAnnotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVC
 
Spring core
Spring coreSpring core
Spring core
 

Similar a Lessons learned from upgrading Thymeleaf

Iwt note(module 2)
Iwt note(module 2)Iwt note(module 2)
Iwt note(module 2)
SANTOSH RATH
 

Similar a Lessons learned from upgrading Thymeleaf (20)

SpringOnePlatform2017 recap
SpringOnePlatform2017 recapSpringOnePlatform2017 recap
SpringOnePlatform2017 recap
 
Spring 4.3-component-design
Spring 4.3-component-designSpring 4.3-component-design
Spring 4.3-component-design
 
Running Java Applications on Cloud Foundry
Running Java Applications on Cloud FoundryRunning Java Applications on Cloud Foundry
Running Java Applications on Cloud Foundry
 
High Performance Cloud Native APIs Using Apache Geode
High Performance Cloud Native APIs Using Apache Geode High Performance Cloud Native APIs Using Apache Geode
High Performance Cloud Native APIs Using Apache Geode
 
Designing, Implementing, and Using Reactive APIs
Designing, Implementing, and Using Reactive APIsDesigning, Implementing, and Using Reactive APIs
Designing, Implementing, and Using Reactive APIs
 
Not Only Reactive - Data Access with Spring Data
Not Only Reactive - Data Access with Spring DataNot Only Reactive - Data Access with Spring Data
Not Only Reactive - Data Access with Spring Data
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep Dive
 
Migrating to Angular 5 for Spring Developers
Migrating to Angular 5 for Spring DevelopersMigrating to Angular 5 for Spring Developers
Migrating to Angular 5 for Spring Developers
 
Cloud-Native Streaming and Event-Driven Microservices
Cloud-Native Streaming and Event-Driven MicroservicesCloud-Native Streaming and Event-Driven Microservices
Cloud-Native Streaming and Event-Driven Microservices
 
Migrating to Angular 4 for Spring Developers
Migrating to Angular 4 for Spring Developers Migrating to Angular 4 for Spring Developers
Migrating to Angular 4 for Spring Developers
 
Enable SQL/JDBC Access to Apache Geode/GemFire Using Apache Calcite
Enable SQL/JDBC Access to Apache Geode/GemFire Using Apache CalciteEnable SQL/JDBC Access to Apache Geode/GemFire Using Apache Calcite
Enable SQL/JDBC Access to Apache Geode/GemFire Using Apache Calcite
 
Use Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile AppsUse Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile Apps
 
Django Tutorial | Django Web Development With Python | Django Training and Ce...
Django Tutorial | Django Web Development With Python | Django Training and Ce...Django Tutorial | Django Web Development With Python | Django Training and Ce...
Django Tutorial | Django Web Development With Python | Django Training and Ce...
 
groovy transforms
groovy transformsgroovy transforms
groovy transforms
 
Enable SQL/JDBC Access to Apache Geode/GemFire Using Apache Calcite
Enable SQL/JDBC Access to Apache Geode/GemFire Using Apache CalciteEnable SQL/JDBC Access to Apache Geode/GemFire Using Apache Calcite
Enable SQL/JDBC Access to Apache Geode/GemFire Using Apache Calcite
 
State of modern web technologies: an introduction
State of modern web technologies: an introductionState of modern web technologies: an introduction
State of modern web technologies: an introduction
 
New in Spring Framework 5.0: Functional Web Framework
New in Spring Framework 5.0: Functional Web FrameworkNew in Spring Framework 5.0: Functional Web Framework
New in Spring Framework 5.0: Functional Web Framework
 
Iwt note(module 2)
Iwt note(module 2)Iwt note(module 2)
Iwt note(module 2)
 
Ed presents JSF 2.2 and WebSocket to Gameduell.
Ed presents JSF 2.2 and WebSocket to Gameduell.Ed presents JSF 2.2 and WebSocket to Gameduell.
Ed presents JSF 2.2 and WebSocket to Gameduell.
 
Reactive Data Access with Spring Data
Reactive Data Access with Spring DataReactive Data Access with Spring Data
Reactive Data Access with Spring Data
 

Más de VMware Tanzu

Más de VMware Tanzu (20)

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About It
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at Scale
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a Product
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready Apps
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And Beyond
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptx
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - French
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - English
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - English
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - French
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software Engineer
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs Practice
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 

Último

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Último (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

Lessons learned from upgrading Thymeleaf

  • 1. Lessons Learned from Upgrading Thymeleaf By Jay Aisenbrey @broadleaf 1
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Q&A
  • 32. Learn More. Stay Connected. jaisenbrey@broadleafcommerce.com Github: cja769 Twitter: @broadleaf 32 #springone@s1p