How to develop nice
JUZUPortlet for eXo Platform
Copyright 2015 eXo Platform
A presentation
by Tuyen - Portal Team Copyright 2015 eXo Platform
Agenda
Copyright 2015 eXo Platform
Enjoy...
1. Introduction to Juzu2. Juzu feature3. Develop Juzu Portlet for eXo Platform4. Migrate your 0.6.2 Juzu Portlet to 1.0.0
You said
JUZUJuzu what…?
Copyright 2015 eXo Platform
JUZU What…?
Copyright 2015 eXo Platform
Juzu is a Web Framework base on MVC
concepts for developing powerful web/portlets
applications
But… WHY Juzu ?
Copyright 2015 eXo Platform
History and technology
Copyright 2015 eXo Platform
● Inspired from Play framework
● Base on MVC concepts
● Modular oriented
● Integrates with IoC frameworks
● Groovy and Mustache template engine
Juzu applications (Chat application)
Copyright 2015 eXo Platform
Juzu applications (homepage and branding portlets)
Copyright 2015 eXo Platform
A review of nice
FEATURESof Juzu
Copyright 2015 eXo Platform
Features of Juzu
Copyright 2015 eXo Platform
● Simplicity
● Typesafe
● Extensibility
Simplicity
Copyright 2015 eXo Platform
@Inject@Path("index.gtmpl")Template index;
@Viewpublic Response.Content index() { return index.ok();}
<action name="hello" class="com.tutorialspoint.struts2.HelloWorldAction" method="execute"> <result name="success">/HelloWorld.jsp</result> </action>● No more XML
● Use Annotation
Typesafe (Detect error at Compile time)
Copyright 2015 eXo Platform
@Inject@Path("index.gtmpl")package.template.index index;
@Viewpublic Response.Content index() { return index.with().location("Ha Noi").ok();}
@Viewpublic Response.Content more() {...}
#{param name=location/}
You are at ${location}.
<a href="@{Controller.more()}">get more information</a>
Typesafe (Detect error at Compile time)
Copyright 2015 eXo Platform
@Inject@Path("index.gtmpl")package.template.index index;
@Viewpublic Response.Content index() { return index.with().location("Ha Noi").ok();}
@Viewpublic Response.Content more() {...}
#{param name=myLocation/}
You are at ${location}.
<a href="@{Controller.more()}">get more information</a>
compile error
Extensibility (Easy to develop and deliver plugin)
Copyright 2015 eXo Platform
public class AjaxService extends ApplicationService {...}
ajax-plugin.jar
org.exoplatform.commons.juzu.ajax.AjaxService
META-INF/services/juzu.impl.plugin.application.ApplicationService
uses the java.util.ServiceLoader discovery mechanism for finding plugin services
How to develop nice
JUZU PORTLETfor eXo Platform
Copyright 2015 eXo Platform
Develop Juzu portlet
Copyright 2015 eXo Platform
● Create new Juzu project● Controller● Business service and Injector● Template● Asset manager● Plugin: Ajax, WebJar
JuZcret…
Copyright 2015 eXo Platform
● Funny Juzu application
● Tutorial: http://blog.exoplatform.com/en/2014/11/18/learn-how-to-develop-great-
juzu-portlets-for-exo-platform
Create new Juzu project
Copyright 2015 eXo Platform
From maven archetype:mvn archetype:generate \ -DarchetypeGroupId=org.juzu \ -DarchetypeArtifactId=juzu-archetype \ -DarchetypeVersion=1.0.0-cr1 \ -DjuzuServer=gatein \ -DgroupId=org.juzu.tutorial \ -DartifactId=tutorial-juzcret \ -Dversion=1.0.0-SNAPSHOT \ -DinteractiveMode=false
Project structure
Copyright 2015 eXo Platform
WEB-INFapplication deployment descriptor
package-info.javaconfiguration for application
ControllerJuzu controller
templatestemplates used in application
Project structure (JuZcret application)
Copyright 2015 eXo Platform
Juzu Controller (simple controller)
Copyright 2015 eXo Platform
public class JuZcretApplication {...}
@View
public Response.Content index() {
return Response.ok("Hello world!!!");
}
@Application(defaultController = org.juzu.tutorial.JuZcretApplication.class)
package org.juzu.tutorial;
package-info.java
Juzu Service
Copyright 2015 eXo Platform
public interface SecretService {...}
@Application(defaultController = ...)@Bindings({ @Binding( value = org.juzu.tutorial.services.SecretService.class, implementation = org.juzu.tutorial.services.SecretServiceMemImpl.class )})package org.juzu.tutorial;
package-info.java
public class SecretServiceMemImpl implements SecretService {...}
Juzu Service (inject to controller)
Copyright 2015 eXo Platform
public interface SecretService {...}
public class JuZcretApplication { @Inject SecretService secretService;
@Inject @Path("secretWall.gtmpl") templates.secretWall secretWall; ...}
@View
public Response.Content index() {
return secretWall.with()
.secretList(secretService.getScretsList()).ok();}
Juzu Template
Copyright 2015 eXo Platform
public class JuZcretApplication { ... @Inject @Path("secretWall.gtmpl") org.juzu.tutorial.templates.secretWall secretWall; ...}
@View
public Response.Content index() {
return secretWall.with().secretsList("My list of secret").ok();
}
#{param name=secretsList/}Here is my secret list: ${secretsList}
secretWall.gtmpl
Juzu Template (template expression)
Copyright 2015 eXo Platform
@View
public Response.Content index() {
return secretWall.with().secretsList(secretService.getSecrets()).ok();
}
#{param name=secretsList/}
<ul class="secret-wall-list"><% secretsList.each { secret -> %> <li> ${secret.message} </li><%}%></ul>
secretWall.gtmpl
Form and Action controller
Copyright 2015 eXo Platform
<form action="@{JuZcretApplication.addSecret()}" method="POST" role="form">
...
<textarea rows="3" name="msg" placeholder="Write your secret here"></textarea> Image URL: <input name="imgURL" placeholder="..."> ... <button type="submit">Share</button></form>
@Actionpublic Response.View addSecret(String msg, String imgURL) { secretService.addSecret(msg, imgURL); return JuZcretApplication_.index();}
JuZcret application
Copyright 2015 eXo Platform
CSS and Javascript
Copyright 2015 eXo Platform
vs
Asset manager (@Stylesheet and Less plugin)
Copyright 2015 eXo Platform
Less plugin will take care of compiling automatically the Less file to CSS file during the maven compilation
<dependency> <groupId>org.juzu</groupId> <artifactId>juzu-plugins-less4j</artifactId> <version>1.0.0-cr1</version></dependency>
@Less(@Stylesheet("styles/juzcret.less"))
@Stylesheets({@Stylesheet(value = "styles/my.css")})
@Assets("*")
package org.juzu.tutorial;
package-info.java
JuZcret UI
Copyright 2015 eXo Platform
Asset manager (@Script and WebJar plugin)
Copyright 2015 eXo Platform
@WebJars(@WebJar("jquery"))@Scripts({ @Script(id = "jquery", value = "jquery/1.10.2/jquery.js"), @Script(value = "javascripts/secret.js", depends = "jquery")}) @Assets("*")package org.juzu.tutorial;
package-info.java
<dependency> <artifactId>juzu-plugins-webjars</artifactId> <groupId>org.juzu</groupId></dependency>
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId></dependency>
Resource Controller
Copyright 2015 eXo Platform
@Resourcepublic Response addComment(String secretId, @Mapped Comment comment, SecurityContext context) { ... Comment result = secretService.addComment(secretId, comment); if (result != null) { return Response.ok(new JSONObject(result).toString()).withMimeType("text/json"); } else { return Response.status(503); }}
@Resource
public Response addLike(String secretId, SecurityContext context) {...}
Controller (map request parameter to Bean types)
Copyright 2015 eXo Platform
@Resourcepublic Response addComment(String secretId, @Mapped Comment comment, SecurityContext context) { ...}
public class Comment extends Model {
private String userId;
private String content;
...
}
Ajax plugin
Copyright 2015 eXo Platform
@Ajax
@Resource
public Response addComment(String secretId, @Mapped Comment comment, SecurityContext context) {...}
$(document).on('click.juzu.secret.addComment', '.btn-comment', function () { ... var jLike = $(this); jLike.jzAjax('JuZcretApplication.addComment()', { data: {...}, success: function (data) { ... } }); return false;});
JuZcret Like and Comment
Copyright 2015 eXo Platform
Internalization and Localization
Copyright 2015 eXo Platform
Juzu support i18n natively in the core. We just need to modify all the labels in all our templates.
<form action="@{JuZcretApplication.enableComment()}" method="POST" role="form">
<h5>&{label.configuration}</h5> <input type="checkbox" name="enableComment" <%=enableComment ? "checked" : "" %>/>
&{label.enableComment} <button type="submit">&{label.save}</button></form>
@InjectResourceBundle bundle;
Controller.java
template.gtmpl
Internalization and Localization
Copyright 2015 eXo Platform
Template (tag)
Copyright 2015 eXo Platform
#{foo}bar#{/foo}
#{foo/}
#{include path=dispatched.gtmpl/}
#{decorate path=box.gtmpl/}
<div style="border: 1px solid black">
#{insert/}
</div>
#{title value=Home/}
#{param name=color/}
Template (Java Custom tag)
Copyright 2015 eXo Platform
public class TitleTag extends TagHandler { public TitleTag() { super("title"); }
@Override public void render(TemplateRenderContext context, Renderable body, Map<String, String> args) throws IOException { String title = args.get("value"); if (title != null) { context.setTitle(title); } body.render(context); }}
Template (Simple Custom tag)
Copyright 2015 eXo Platform
@Application@Tags(@Tag(name = "mytag", path = "mytag.gtmpl"))package my.application;
Hello ${parameters.name}
#{mytag name=”my name”/}
mytag.gtmpl
template
Template (reuse simple custom tag)
Copyright 2015 eXo Platform
custom-tags.jar
my.application.tags.mytag
META-INF/services/juzu.template.TagHandler
@Application@Tags(@Tag(name = "mytag", path = "mytag.gtmpl"))package my.application;
How to
MIGRATEfrom 0.6.2 to 1.0.0
Copyright 2015 eXo Platform
Controller method
Copyright 2015 eXo Platform
Controller method must return Response object
@Viewpublic void index() { index.render(parameters);}
@Viewpublic Response index() { return index.ok(parameters);}
Template#render() is removed
Copyright 2015 eXo Platform
use method juzu.template.Template#ok()
@Viewpublic void index() { index.render(parameters);}
@Viewpublic Response index() { return index.ok(parameters);}
RenderContext is removed
Copyright 2015 eXo Platform
If you want to use these context objects:juzu.request.ApplicationContextjuzu.request.UserContextjuzu.request.SecurityContext….
Just inject them into controller method
@Viewpublic Response.Content index(ApplicationContext applicationContext, SecurityContext securityContext, UserContext userContext){...}
Localization
Copyright 2015 eXo Platform
<form action="@{JuZcretApplication.enableComment()}" method="POST" role="form">
<h5>&{label.configuration}</h5> <input type="checkbox" name="enableComment" <%=enableComment ? "checked" : "" %>/>
&{label.enableComment} <button type="submit">&{label.save}</button></form>
@InjectResourceBundle bundle;
Controller.java
template.gtmpl
class *Plugin is renamed to *Service
Copyright 2015 eXo Platform
public class AjaxService extends ApplicationService {...}
ajax-plugin.jar
org.exoplatform.commons.juzu.ajax.AjaxService
META-INF/services/juzu.impl.plugin.application.ApplicationService
ApplicationPlugin
rename to
META-INF/services/juzu.impl.plugin.application.ApplicationPlugin
rename to
It’s time for
THANK YOUsee you soon ...
Copyright 2015 eXo Platform