Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

eXoer on the grill: How to develop nice Juzu Portlet for eXo Platform

10,677 views

Published on

www.exoplatform.com - eXo Portal team presents Juzu 1.0 and how to develop nice Juzu portlets for eXo Platform.

eXoers on the Grill aims to provide some incentive & fresh air for our staff in order to constantly re-think our methods, spread good practices, promote some technology or tools, generate ideas, etc... All the teams are invited to contribute by picking up some hot topics of their choice and spread to other teams.

Published in: Software
  • Be the first to comment

eXoer on the grill: How to develop nice Juzu Portlet for eXo Platform

  1. 1. How to develop nice JUZU Portlet for eXo Platform Copyright 2015 eXo Platform
  2. 2. A presentation by Tuyen - Portal Team Copyright 2015 eXo Platform
  3. 3. Agenda Copyright 2015 eXo Platform Enjoy... 1. Introduction to Juzu 2. Juzu feature 3. Develop Juzu Portlet for eXo Platform 4. Migrate your 0.6.2 Juzu Portlet to 1.0.0
  4. 4. You said JUZU Juzu what…? Copyright 2015 eXo Platform
  5. 5. JUZU What…? Copyright 2015 eXo Platform Juzu is a Web Framework base on MVC concepts for developing powerful web/portlets applications
  6. 6. But… WHY Juzu ? (Too many MVC web framework?) Copyright 2015 eXo Platform
  7. 7. WHY Juzu ? (Why don’t use existing one) Copyright 2015 eXo Platform ● All framework target for developing web app ● Too Complex in configuration with XML ● Play framework is simple and good but does not follow JavaEE standard Juzu combine idea of Play framework with JavaEE standard and target for developing both Portlet and Web application.
  8. 8. 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
  9. 9. Juzu applications (Chat application) Copyright 2015 eXo Platform
  10. 10. Juzu applications (homepage and branding portlets) Copyright 2015 eXo Platform
  11. 11. A review of nice CONCEPTS of Juzu Copyright 2015 eXo Platform
  12. 12. Concepts of Juzu Copyright 2015 eXo Platform ● Simplicity ● Typesafe ● Extensibility
  13. 13. Simplicity Copyright 2015 eXo Platform @Inject @Path("index.gtmpl") Template index; @View public 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
  14. 14. Typesafe (Detect error at Compile time) Copyright 2015 eXo Platform @Inject @Path("index.gtmpl") package.template.index index; @View public Response.Content index() { return index.with().location("Ha Noi").ok(); } @View public Response.Content more() {...} #{param name=location/} You are at ${location}. <a href="@{Controller.more()}">get more information</a>
  15. 15. Typesafe (Detect error at Compile time) Copyright 2015 eXo Platform @Inject @Path("index.gtmpl") package.template.index index; @View public Response.Content index() { return index.with().location("Ha Noi").ok(); } @View public Response.Content more() {...} #{param name=myLocation/} You are at ${location}. <a href="@{Controller.more()}">get more information</a> compile error
  16. 16. 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
  17. 17. How to develop nice JUZU PORTLET for eXo Platform Copyright 2015 eXo Platform
  18. 18. Develop Juzu portlet Copyright 2015 eXo Platform ● Create new Juzu project ● Controller ● Business service and Injector ● Template ● Asset manager ● Plugin: Ajax, WebJar
  19. 19. 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
  20. 20. 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
  21. 21. Project structure Copyright 2015 eXo Platform WEB-INF application deployment descriptor package-info.java configuration for application Controller Juzu controller templates templates used in application
  22. 22. Project structure (JuZcret application) Copyright 2015 eXo Platform
  23. 23. 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
  24. 24. 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 {...}
  25. 25. 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(); }
  26. 26. 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
  27. 27. 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
  28. 28. 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> @Action public Response.View addSecret(String msg, String imgURL) { secretService.addSecret(msg, imgURL); return JuZcretApplication_.index(); }
  29. 29. JuZcret application Copyright 2015 eXo Platform
  30. 30. CSS and Javascript Copyright 2015 eXo Platform vs
  31. 31. 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
  32. 32. JuZcret UI Copyright 2015 eXo Platform
  33. 33. 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>
  34. 34. Resource Controller Copyright 2015 eXo Platform @Resource public 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) {...}
  35. 35. Controller (map request parameter to Bean types) Copyright 2015 eXo Platform @Resource public Response addComment(String secretId, @Mapped Comment comment, SecurityContext context) { ... } public class Comment extends Model { private String userId; private String content; ... }
  36. 36. 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; });
  37. 37. JuZcret Like and Comment Copyright 2015 eXo Platform
  38. 38. 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> @Inject ResourceBundle bundle; Controller.java template.gtmpl
  39. 39. Internalization and Localization Copyright 2015 eXo Platform
  40. 40. 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/}
  41. 41. 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); } }
  42. 42. 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
  43. 43. 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;
  44. 44. Juzu 1.0 New Features Copyright 2015 eXo Platform
  45. 45. Juzu 1.0 (new features) Copyright 2015 eXo Platform ● Asset minification ● Bean validation plugin ● Request parameter types ● JSON responding ● Jackson plugin ● Application error handler
  46. 46. Juzu 1.0 New Features (asset minification) Copyright 2015 eXo Platform @Scripts(@Script(value = "jquery.js", minified = "jquery.min.js")) package my.application; @Scripts(@Script(value = "jquery.js"), minifier = NormalizeJSMinifier.class), package my.application; Juzu allows to provide a minified version of an asset that will be used in prod run mode @Scripts(@Script(value = "jquery.js"), minifier = ClosureMinifier.class), package my.application; On-the-fly minification Generate minified version at runtime
  47. 47. Juzu 1.0 New Features (asset minification - Less plugin) Copyright 2015 eXo Platform In Less plugin: a minify option can be used to minify generated css file. This option will trim the white-space when processing the file @Less(@Stylesheet(value = "stylesheet.less", minify = true)) package my.application;
  48. 48. Juzu 1.0 New Features (Request parameter type) Copyright 2015 eXo Platform @Action @Route("/login") public Response login(@Mapped User user) { ... } @Action public Response.Content sum(Integer left, int right) { ... } @View public Response.Content show(@Format("yyyy.MM.dd G 'at' HH:mm:ss z") Date date) throws Exception { ... } @View public Response.Content sum(int[] values) { ... } Primary type Date time Bean type Multivalued type
  49. 49. Juzu 1.0 New Features (JSON Responding - too complex in 0.6) Copyright 2015 eXo Platform private Response.Content<Stream.Char> createJSONResponse(final Map<String, String> data) { return new Response.Content<Stream.Char>(200, Stream.Char.class) { @Override public String getMimeType() { return "application/json"; } @Override public void send(Stream.Char stream) throws IOException { stream.append("{"); Iterator<Map.Entry<String, String>> i = data.entrySet().iterator(); while (i.hasNext()) { Map.Entry<String, String> entry = i.next(); stream.append(""" + entry.getKey() + """).append(":").append(""" + entry.getValue() + """); if (i.hasNext()) { stream.append(","); } } stream.append("}"); } }; } }
  50. 50. Juzu 1.0 New Features (JSON Responding - very easily in 1.0.0) Copyright 2015 eXo Platform @Resouces public Response.Content getResources() { JSONObject json = new JSONObject(); parameters.put("key", "value"); … return Response.ok(json.toString()).withMimeType("application/json"); }
  51. 51. Juzu 1.0 New Features (Jackson plugin) Copyright 2015 eXo Platform @Action public void post(com.fasterxml.jackson.databind.JsonNode tree) { ... } @Action @Route("/post") public Response.View action(@Jackson MyObj obj) throws IOException { ... } The Jackson plugin decodes json entities using the Jackson framework. It can decode to a Jackson native tree or perform mapping to Java object using Jackson mapper.
  52. 52. Juzu 1.0 New Features (Jackson plugin - response JSON) Copyright 2015 eXo Platform Producing a JSON response can done using the Jackson plugin. It can encode a native JsonTree or an object using the Jackson mapper. @View @MimeType.JSON @Jackson public MyObj index() { return new MyObj("Hello World"); } @View @MimeType.JSON public TreeNode index() { JsonNodeFactory factory = JsonNodeFactory.instance; return factory.factory.textNode("Hello World"); }
  53. 53. Juzu 1.0 New Features (Validation) Copyright 2015 eXo Platform @View public Response.Content doSomething(@javax.validation.constraints.NotNull String s) { return Response.ok("The parameter 's' should never be null"); } Juzu provides controller handler parameter validation via the Bean Validation framework.
  54. 54. Juzu 1.0 New Features (Application error handler) Copyright 2015 eXo Platform public class ErrorHandler implements Handler<Response.Error, Response> { @Override public Response handle(Response.Error argument) { return Response.content(500, "An error occured"); } } @Application(errorController = ErrorHandler.class) package my.application; @View public Response.Content doSomething(@javax.validation.constraints.NotNull String s) { return Response.ok("The parameter 's' should never be null"); } If validation error package-info.java
  55. 55. How to MIGRATE from 0.6.2 to 1.0.0 Copyright 2015 eXo Platform
  56. 56. Controller method Copyright 2015 eXo Platform Controller method must return Response object @View public void index() { index.render(parameters); } @View public Response index() { return index.ok(parameters); }
  57. 57. Template#render() is removed Copyright 2015 eXo Platform use method juzu.template.Template#ok() @View public void index() { index.render(parameters); } @View public Response index() { return index.ok(parameters); }
  58. 58. RenderContext is removed Copyright 2015 eXo Platform If you want to use these context objects: juzu.request.ApplicationContext juzu.request.UserContext juzu.request.SecurityContext …. Just inject them into controller method @View public Response.Content index(ApplicationContext applicationContext, SecurityContext securityContext, UserContext userContext){...}
  59. 59. 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> @Inject ResourceBundle bundle; Controller.java template.gtmpl
  60. 60. 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
  61. 61. It’s time for THANK YOU see you soon ... Copyright 2015 eXo Platform

×