Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Wicket from Designer to Developer
1. Wicket from Designer to Developer
Marcello Teodori
marcello.teodori@jugmilano.it – JUG Milano
2. A few words about the speaker
• longtime JUG Leader, now only from “remote”, for JUG Milano
• moderator for SpringFramework-IT and Groovy Italian User Group
mailing lists
• 15y of Java development, from mobile to web
• now based in London, working as Lead Engineer for Idea Plane, a
startup specialized in Enterprise Social Network solutions
• more twitterer: http://twitter.com/magomarcelo
than blogger: http://magomarcelo.blogspot.com
Marcello Teodori 2
marcello.teodori@jugmilano.it – JUG Milano
3. A web application tale
• no analysts vs. developers this time
• it’s you, just the development team of a web
application
– designers, from PSD to HTML/CSS/JavaScript
– developers, Java (or your favorite server-side thing)
separated by the HTTP protocol...
united by a template!
Marcello Teodori 3
marcello.teodori@jugmilano.it – JUG Milano
4. My problem
• As a developer of a web application
• I want to avoid spending time rewriting my
templates from scratch if the design changes
• so that I can deliver on schedule
• ...and the customer is happy!
Marcello Teodori 4
marcello.teodori@jugmilano.it – JUG Milano
5. Someone’s else problem
• As a designer of a web application
• I want to be free to make changes
• so that my design meets requirements
• ...and the customer is happy!
Marcello Teodori 5
marcello.teodori@jugmilano.it – JUG Milano
6. So happy together!
Let’s try and define
an iterative workflow
which allows going
back and forth from
design to develop
phase without yes we can!
frictions...
Marcello Teodori 6
marcello.teodori@jugmilano.it – JUG Milano
7. Context: the good ol’ JSP Model 2
maybe not just
JSP anymore, but
templates are still
where design and
development meet!
Marcello Teodori 7
marcello.teodori@jugmilano.it – JUG Milano
8. Templates Styles
• Imperative or “pull”
– active, contain logic to retrieve data
– the template pulls data from the controller
• Declarative or “push”
– passive, do not contain logic,
they just describe the markup
– the controller parses the template
and pushes data on placeholders
Marcello Teodori 8
marcello.teodori@jugmilano.it – JUG Milano
9. pure JSP
<h1>Sign Up</h1>
• logic in the template <form action="submit.html">
<% if (! errors.isEmpty()) { %>
can contain anything!
<div id="errors" class="error_messages">
<h2>Form is invalid</h2>
<ul>
• good for prototyping <% for (String message : errors) { %>
<li><%= message %></li>
<% } %>
very simple things </ul>
</div>
<% } %>
• when viewing as static <p>
<label for="email"><%= email.getLabel() %></label><br/>
html anything gets <input type="text" value="<%= email.getValue() %>"/><br/>
</p>
rendered <p>
<label for="password"><%= password.getLabel() %></label><br/>
<input type="password" value="<%= password.getValue() %>"/><br/>
</p>
<p class="button"><input type="submit" value="Create User" /></p>
</form>
Marcello Teodori 9
marcello.teodori@jugmilano.it – JUG Milano
10. JSP + JSTL
<h1>Sign Up</h1>
• logic gets limited and <form action="submit.html">
<c:if test="${not empty errors}">
<div id="errors" class="error_messages">
takes the shape of tags, <h2>Form is invalid</h2>
<ul>
which are not displayed <c:forEach var="message" items="${errors}">
<li>${message}</li>
as static html </ul>
</c:forEach>
</div>
• no default values for </c:if>
<p>
placeholders to display
<label for="email">${email.label}</label><br/>
<input type="text" value="${email.value}"/><br/>
</p>
• expressions are fragile <p>
<label for="password">${password.label}</label><br/>
<input type="password" value="${password.value}"/><br/>
• can still add scriptlets </p>
<p class="button"><input type="submit" value="Create User" /></p
</form>
Marcello Teodori 10
marcello.teodori@jugmilano.it – JUG Milano
11. Velocity
<h1>Sign Up</h1>
• main Spring MVC <form action="submit.html">
#if( $errors.size() > 0 )
<div id="errors" class="error_messages">
option from docs <h2>Form is invalid</h2>
<ul>
#foreach( $message in $errors )
• not tied to servlet API <li>$message</li>
#end
</ul>
• same as JSTL with </div>
#end
custom language
<p>
<label for="email">$email.label</label><br/>
<input type="text" value="$email.value"/><br/>
</p>
• few good editors... <p>
<label for="password">$password.label</label><br/>
<input type="password" value="$password.value"/><br/>
</p>
<p class="button"><input type="submit" value="Create User" /></p>
</form>
Marcello Teodori 11
marcello.teodori@jugmilano.it – JUG Milano
12. Off the Java track: Ruby on Rails and ERB
<h1>Sign Up</h1>
• again imperative <%= form_for @user do |f| %>
<% if @user.errors.any? %>
<div id="errors" class="error_messages">
• fragments can be <h2>Form is invalid</h2>
<ul>
called as partial vs.
<% for message in @user.errors %>
<li><%= message %></li>
<% end %>
full page </ul>
</div>
<p>
• in the end not that <%= f.label :email %><br/>
<%= f.text_field :email %><br/>
</p>
different from JSP! <p>
<%= f.label :password %><br/>
<%= f.text_field :password %><br/>
</p>
<p class="button"><input type="submit" value="Create User" /></p>
<% end %>
Marcello Teodori 12
marcello.teodori@jugmilano.it – JUG Milano
13. going declarative: JSF with Facelets
• an HTML which validates as XHTML <html xmlns:h="http://java.sun.com/jsf/html">
<body>
but is not really your HTML, try <h:form>
displaying it! <h:messages/>
<p>
• lots of ready made component <label for="email">Email: </label><br/>
<h:inputText value="#{user.email}"/><br/>
libraries which turn into html/css/js </p>
like magic <p>
<label for="password">Password: </label><br/>
• good for developers who cannot <h:inputText value="#{user.password}"/><br/>
</p>
afford to take care of frontend code <p>
<label for="confirm">Password confirmation: </label><br
• deadly for designers who have to <h:inputText value="#{user.confirmPassword}"/><br/>
</p>
adapt to the output <p class="button">
<h:commandButton action="#{user.create()}" value="Creat
• creating custom components </p>
is not that easy </form>
Marcello Teodori 13
marcello.teodori@jugmilano.it – JUG Milano
14. enter Wicket for designer friendly templates
<html xmlns:wicket="http://wicket.apache.org">
<body>
• HTML wicket templates still render <h1>Sign Up</h1>
properly as static HTML <form wicket:id="form">
<div wicket:id="errors" id="errors" class="error_messages">
<ul>
• placeholders display actual text <li>Input is incorrect</li>
instead of expressions, which is </ul>
</div>
useful for prototyping <p>
<label for="email">Email: </label><br/>
• custom elements and attributes from <input wicket:id="username" type="email" id="email" value=""
</p>
the wicket namespace are not <p>
recognized and ignored by the <label for="password">Password: </label><br/>
<input wicket:id="password" type="password" id="password" val
browser, at least most of them... </p>
<p>
• custom components are easy to <label for="confirm">Password confirmation: </label><br/>
<input wicket:id="confirmPassword" type="password" id="confir
create </p>
<p class="button"><input type="submit" value="Create User" id="
</form>
Marcello Teodori 14
marcello.teodori@jugmilano.it – JUG Milano
15. What’s behind the HTML template? Just Java! 1/2
• a custom SignUpPage class public class SignUpPage extends WebPage {
private User user = new User();
extending WebPage private TextField<String> usernameTextField, passwordTextField, confirmPass
• added to our page, with same public SignUpPage() {
wicket id as in the template a Form<User> form = new Form<User>("form") {
@Override
signup Form component protected void onSubmit() {
// validate password and confirm match
if (Strings.isEqual(password, confirmPassword)) {
– 3 text fields for email, password // user creation
and confirm } else {
error("password do not match");
– 1 FeedbackPanel component }
}
– onSubmit override };
form.add(usernameTextField = new EmailTextField("username", Model.of(""
form.add(passwordTextField = new PasswordTextField("password", Model.of
• wicket component tree in Java form.add(confirmPasswordTextField = new PasswordTextField("confirmPassw
class and template must match! form.add(new FeedbackPanel("errors"));
add(form);
}
}
Marcello Teodori 15
marcello.teodori@jugmilano.it – JUG Milano
16. What’s behind the HTML template? Just Java! 2/2
package ...;
A custom WicketApplication class
public class WicketApplication extends WebApplication {
extending WebApplication:
@Override
• must be configured in web.xml public Class<HomePage> getHomePage() {
return HomePage.class;
• should contain as a minimum: }
• pointer to home page class @Override
public void init() {
• our application settings super.init();
// add your configuration here
• mount point for our page mountPage("/SignUpPage.html", SignUpPage.class);
}
}
Marcello Teodori 16
marcello.teodori@jugmilano.it – JUG Milano
17. What is Wicket?
a web framework which provides
a stateful object-oriented programming model
on top of the stateless HTTP protocol
...with just Java and HTML!
Marcello Teodori 17
marcello.teodori@jugmilano.it – JUG Milano
18. Quickstart, everything you need to start!
.myproject
| pom.xml
|
Creating the project - with Maven ---src
+---main
To create your project, copy and paste the command | +---java
| | ---com
line generated after typing in the groupId, artifactId and | | ---mycompany
version. | | HomePage.html
| | HomePage.java
| | WicketApplication.java
| |
| +---resources
| | log4j.properties
| |
| ---webapp
| ---WEB-INF
| web.xml
|
---test
---java
---com
---mycompany
Start.java
Marcello Teodori 18
marcello.teodori@jugmilano.it – JUG Milano
19. in Wicket everyone works in their comfort zone
– developers work with Java only
• no XML configurations beyond the wicket filter in web.xml
• creation of components via new, extension via extend or
adding “behaviors”
• pages are built following the composite pattern
– designers work in HTML only
• no scriptlets
• no expression language
• CSS and JS included, obviously ;)
Marcello Teodori 19
marcello.teodori@jugmilano.it – JUG Milano
20. Digging a little deeper into Wicket classes
Marcello Teodori 20
marcello.teodori@jugmilano.it – JUG Milano
21. some additional useful wicket elements
• wicket:extend and wicket:child
– provide markup inheritance
• wicket:head
– provide content for HTML header
• wicket:remove
– exclude from rendering markup useful only at design time
• wicket:enclosure
– ties the visibility of a block of markup to the one of a specific component
• wicket:container
– allow dynamic rendering outside an HTML element
• wicket:message (also available as attribute)
– allows string replacement from localized messages
Marcello Teodori 21
marcello.teodori@jugmilano.it – JUG Milano
22. Localization in Wicket
• typical messages implemented by default as properties files
– extended also to XML properties version and or also utf8
– placeholders bean expressions beyond javax.text.MessageFormat
– lookup follows the hierarchy, i.e.:
• MyApplication.properties
• MyPage.properties
• MyComponent.properties
• one step beyond
– also full templates can be localized! HomePage.html => HomePage_it.html
– additional options for template selection: template_variation_style_locale.html
• style set on session
• variation set on component
Marcello Teodori
marcello.teodori@jugmilano.it – JUG Milano
22
23. Providing a mobile version of a template
• using style and variation we can
detect and use a different template
for a mobile browser
• a specific mobile style on the session
can be set for example using simple
browser sniffing
• better yet, Wicket provides a
ClientInfo object for detecting
browser capabilities
Marcello Teodori 23
marcello.teodori@jugmilano.it – JUG Milano
24. Demo Time
Marcello Teodori 24
marcello.teodori@jugmilano.it – JUG Milano
26. My personal Wicket story
• I thought I had tried anything in the Java web framework space...
• 2005 overlooked wicket at a presentation of JavaPolis (now Devoxx)
as yet another interesting approach but without proper mindshare
• friends at JUG Milano using it and praising it for its clean object-
oriented approach on the java “developer” side of things
• 2010 bumped into wicket as the insourcing of a wicket code base
was my first activity in my current job as lead engineer at Idea Plane
• 2011 engineering the prototype code, I was impressed by the
resilience to bugs, I discovered a new friend
• 2012 don’t ever name JSP to me again!!!
Marcello Teodori 26
marcello.teodori@jugmilano.it – JUG Milano
27. AJAX, the elephant in the room
How Wicket deals with AJAX?
• developer friendly approach:
– Button => AjaxButton => AjaxFallbackButton
– AjaxDefaultTarget => add modified components
– AjaxDefaultBehaviour & wicket-ajax.js
• designer friendly approach:
– AjaxBehaviour produces json
– direct AJAX call via JavaScript,
e.g. using jQuery
Marcello Teodori 27
marcello.teodori@jugmilano.it – JUG Milano
28. There’s more than HTML templates!
Wicket as a web framework provides a lot more:
• form processing
• type-safe access to session
• conversation support via page serialization
• data binding via model classes
• resource (CSS/JS) optimization
• integration with popular dependency injection frameworks
• but most of all, pluggable hooks to customize any feature it
provides, you’re never left alone!
Marcello Teodori 28
marcello.teodori@jugmilano.it – JUG Milano
29. But that’s too much for me!
• as good as it is, Wicket is not everyone’s
cup of tea
• Wicket can be stateless, but it’s not its
main use case
• even when stateless, Wicket relies on the
Servlet session
• you have already a big code base maybe
on another framework like Spring MVC
Marcello Teodori 29
marcello.teodori@jugmilano.it – JUG Milano
30. Thymeleaf
• http://www.thymeleaf.org/ <table>
<thead>
• HTML template engine with <tr>
<th th:text="#{msgs.headers.name}">Name</th>
similar designer friendly <th th:text="#{msgs.headers.price}">Price</th>
</tr>
approach to Wicket </thead>
<tbody>
• works with stateless <tr th:each="prod : ${allProducts}">
<td th:text="${prod.name}">Oranges</td>
frameworks like Spring MVC <td th:text="$
{#numbers.formatDecimal(prod.price,1,2)}">0.99</td>
or Play </tr>
</tbody>
</table>
• can work standalone with no
web dependency (e.g. to
generate HTML emails)
Marcello Teodori 30
marcello.teodori@jugmilano.it – JUG Milano
31. Some Useful References
• The Apache Wicket web site http://wicket.apache.org/
• The Wicket user mailing list
– on nabble: http://apache-wicket.1842946.n4.nabble.com/
• Wicket in Action http://wicketinaction.com/
– essential book
– wicket 1.3 but still very relevant
• example code for this presentation
– https://github/mteodori/d2d-wicket-webapp
Marcello Teodori 31
marcello.teodori@jugmilano.it – JUG Milano
32. Some Thank Yous
• http://www.jugmilano.it/ - JUG Milano & yet another
discussion on the best web framework on our mailing list!
• http://www.ideaplane.com - for giving me some spare time
to prepare this and meet friends in Rome
• http://www.gitenterprise.com - startup friends support!
• http://www.liludori.com/ - pictures from the wonderful world
of Liludori, courtesy of Mauro Gandini and Eloisa Scichilone
Marcello Teodori 32
marcello.teodori@jugmilano.it – JUG Milano
33. shameless plug: IdeaPlane is hiring!
Work on our leading Enterprise Social Network platform in our London office
We’re looking for a talented
• Technical Director/Lead
• Scrum Master
• Java Developer
and more…check out our website at http://ideaplane.com for additional details.
What we offer:
• an opportunity to work in the social media space
• new technology
• bike rack, foosball table and an office in central London
• free snacks
• great people!
Marcello Teodori 33
marcello.teodori@jugmilano.it – JUG Milano
34. Questions & (hopefully) Answers
Marcello Teodori 34
marcello.teodori@jugmilano.it – JUG Milano