{"id":4300,"date":"2013-01-24T08:55:27","date_gmt":"2013-01-24T16:55:27","guid":{"rendered":"http:\/\/localhost\/exoblog\/?p=4300"},"modified":"2013-01-24T08:55:27","modified_gmt":"2013-01-24T16:55:27","slug":"juzu-day-3-the-coolness","status":"publish","type":"post","link":"https:\/\/www.exoplatform.com\/blog\/juzu-day-3-the-coolness\/","title":{"rendered":"Juzu Day 3: The Coolness"},"content":{"rendered":"<p><em>Today is the last of my three days on Juzu and I want to show some nice features you can find inside.<\/em><\/p>\n<p>If you want to start from Day 1, you can take a look in the previous posts:<br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/2013\/01\/22\/three-days-with-juzu-write-a-killer-app\/\">Three Days with Juzu: Write a Killer App<\/a>;<br \/>\n&#8211; Juzu Day 2: Real Web Apps as well.<\/p>\n<p>So, if you want to see some nice gems, it&#8217;s here.<\/p>\n<p><!--more--><\/p>\n<h2>All the Coolness<\/h2>\n<p>We know how to write an app, but do we know how to write something cool, something you say &#8220;it&#8217;s fucking great, man!&#8221; when you look at it? Of course, there are a number of other gems in Juzu.<\/p>\n<h3>Ajax + jQuery<\/h3>\n<p>The first one, and it&#8217;s a big one, is about Ajax calls. We saw at the beginning of this &#8220;quite long&#8221; article that you can declare a resource with <em>@Ajax<\/em> annotation, like here in <a href=\"https:\/\/github.com\/exo-addons\/chat-application\/blob\/master\/application\/src\/main\/java\/org\/benjp\/portlet\/chat\/ChatApplication.java#L122\" target=\"_blank\" rel=\"noopener\" class=\"broken_link\">maintainSession<\/a>:<\/p>\n<pre class=\"lang:default decode:true\">@Ajax\n@Resource\npublic Response.Content maintainSession()\n{\n  return Response.ok(\"OK\").withMimeType(\"text\/html; charset=UTF-8\").withHeader(\"Cache-Control\", \"no-cache\");\n}<\/pre>\n<p>It&#8217;s about Ajax, right? So, we added jQuery as an asset in the <a href=\"https:\/\/github.com\/exo-addons\/chat-application\/blob\/master\/application\/src\/main\/java\/org\/benjp\/portlet\/chat\/package-info.java#L32\" target=\"_blank\" rel=\"noopener\" class=\"broken_link\">packaging-info<\/a>:<\/p>\n<pre class=\"lang:default decode:true\">...\n        scripts = {\n                @Script(src = \"js\/jquery-1.7.1.min.js\", id = \"jquery\"),\n  ...<\/pre>\n<p>Thanks to the amazing stuff that is done under the hood by Julien, Juzu will detect you&#8217;re using jQuery and will generate specific jQuery objects so you can call your method very easily from within the\u00a0JavaScript. Let&#8217;s take a look inside <a href=\"https:\/\/github.com\/exo-addons\/chat-application\/blob\/master\/application\/src\/main\/webapp\/js\/chat.js#L18\" target=\"_blank\" rel=\"noopener\" class=\"broken_link\">chat.js<\/a> to see this:<\/p>\n<pre class=\"lang:default decode:true\">var $chatApplication = $(\"#chat-application\");\nvar jzMaintainSession = $chatApplication.jzURL(\"ChatApplication.maintainSession\");\n..\nfunction maintainSession() {\n  $.ajax({\n    url: jzMaintainSession,\n    success: function(response){\n      console.log(\"Chat Session Maintained : \"+response);\n    },\n    error: function(response){\n      chatSessionInt = clearInterval(chatSessionInt);\n    }\n  });\n}<\/pre>\n<p>There&#8217;s also <em>$.jzLoad<\/em> and <em>$.jzAjax<\/em> methods if you want a shortcut to jQuery <em>$.ajax()<\/em> method, like:<\/p>\n<pre class=\"lang:default decode:true\">$(this).jzLoad(\"ChatApplication.foo\"); \/\/will load data in 'this'<\/pre>\n<p>For me, it&#8217;s a killer feature because it makes your code so much easier to read.<\/p>\n<h3>Less<\/h3>\n<p>I already talked a little bit about Less integration but here is a quick example about how great this is to write CSS.<\/p>\n<p>The fact is I like Less but without this integration, I could certainly not use it. But now, since it&#8217;s part of Juzu, I have no excuse since it takes just a line to use Less.<\/p>\n<p>So, let&#8217;s say you want to define emoticons in your CSS. Usually, you will do this:<\/p>\n<pre class=\"lang:default decode:true\">.emoticon-smile{\n  background:url('\/chat\/img\/emoticons\/smile.png') no-repeat 0px 0px;\n}\n.emoticon-big-smile{\n  background:url('\/chat\/img\/emoticons\/bigsmile.png') no-repeat 0px 0px;\n}\n.emoticon-eye-blink{\n  background:url('\/chat\/img\/emoticons\/eyeblink.png') no-repeat 0px 0px;\n}\n.emoticon-no-voice{\n  background:url('\/chat\/img\/emoticons\/novoice.png') no-repeat 0px 0px;\n}\n.emoticon-sad{\n  background:url('\/chat\/img\/emoticons\/sad.png') no-repeat 0px 0px;\n}\n.emoticon-surprise{\n  background:url('\/chat\/img\/emoticons\/surprise.png') no-repeat 0px 0px;\n}<\/pre>\n<p>One thing I hate is copy\/pasting the some code; same thing goes for CSS, I hate it like that. 1) It&#8217;s ugly. 2) It&#8217;s hard to read. With Less integration in Juzu, you just need to do this in emoticons.less:<\/p>\n<pre class=\"lang:default decode:true\">.background-emoticon(@image) {\n  background: url('@{imgEmoticonPath}@{image}') no-repeat 0px 0px;\n}\n.emoticon-smile {\n  .background-emoticon('smile.png');\n}\n.emoticon-big-smile {\n  .background-emoticon('bigsmile.png');\n}\n.emoticon-eye-blink {\n  .background-emoticon('eyeblink.png');\n}\n.emoticon-no-voice {\n  .background-emoticon('novoice.png');\n}\n.emoticon-sad {\n  .background-emoticon('sad.png');\n}\n.emoticon-surprise {\n  .background-emoticon('surprise.png');\n}<\/pre>\n<p>Now, take a look at that, it&#8217;s far better, isn&#8217;t it? \ud83d\ude42<\/p>\n<p>You can even do more tricky stuff with Less like, for example, in the panels.less:<\/p>\n<pre class=\"lang:default decode:true\">.chat-panel (@heightParam, @colorParam) {\n  float: left;\n  z-index: 10;\n  position: absolute;\n  width: @width;\n  height: @heightParam;\n  color: @colorParam;\n  padding: 50px 0px 0px;\n  text-align: center;\n  font-size: 14px;\n  font-weight: normal;\n}\n\n.chat-error-panel, .chat-login-panel, .chat-about-panel, .chat-demo-panel {\n  .chat-panel((@height - 51), white);\n  background-color: @colorBgPanel;\n}\n.chat-help-panel {\n  .chat-panel((@height - 1), black);\n  background:url('@{imgPath}help-panel.png') no-repeat 0px 0px;\n  padding: 0px 0px 0px 0px;\n}\n.chat-sync-panel {\n  .chat-panel((@height - 51), white);\n}<\/pre>\n<p>Here, you declare a class with arguments and you can even do some math with your params (like <em>@height &#8211; 51<\/em>). I can&#8217;t thank enough all the developers out there who provide jQuery, Bootstrap, Less and all these kinds of life savers.<\/p>\n<h3>Responsive Design<\/h3>\n<p>There&#8217;s a big trend on responsive design. If you don&#8217;t really know what it is, I invite you to spend even more time watching a video on this:<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/vimeo.com\/55342263\" target=\"_blank\" rel=\"noopener\">Responsive Design<\/a> from <a href=\"http:\/\/vimeo.com\/user1241097\" target=\"_blank\" rel=\"noopener\">Benjamin Paillereau<\/a> on <a href=\"http:\/\/vimeo.com\/55342263\" target=\"_blank\" rel=\"noopener\">Vimeo<\/a>.<\/p>\n<p>To make it simpler, it&#8217;s about developing <strong>one app to rule them all!<\/strong>\u00a0You write once and it will adapt automatically depending on whether accessing your site or app from a desktop, a small notebook, an iPad, an iPhone; you name it.<\/p>\n<p>All you need to do is two things:<\/p>\n<ul>\n<li>Manage viewport with a viewport metatag in your html header;<\/li>\n<li>Create multiple CSS for each media (small screen, large screens, print, etc).<\/li>\n<\/ul>\n<h4>Viewport metatag<\/h4>\n<p>Again, thanks to Juzu&#8217;s coolness, it will only take 10 seconds for this step. Just add the right <em>withMetaTag<\/em> in your render and you&#8217;re done &#8211; <a href=\"https:\/\/github.com\/exo-addons\/chat-application\/blob\/master\/application\/src\/main\/java\/org\/benjp\/portlet\/chat\/ChatApplication.java#L103\" target=\"_blank\" rel=\"noopener\" class=\"broken_link\">like in the chat<\/a>:<\/p>\n<pre class=\"lang:default decode:true\">indexDemo.render().withMetaTag(\"viewport\", \"width=device-width, initial-scale=1.0\");<\/pre>\n<p>It&#8217;s that easy!<\/p>\n<h4>Media in CSS<\/h4>\n<p>Well, this is where Less integration is a killer and why you should really use it!<\/p>\n<p>It may be a pain in the *** to manage this but not with Less. Again, thanks to Less integration in Juzu, it&#8217;s just a few lines of code and thinking your CSS the right way &#8211; like for the Chat app:<\/p>\n<pre class=\"lang:default decode:true\">@media (min-width: 768px) and (max-width: 1199px) {\n  @height:                      700px;\n  @width:                       760px;\n  @heightMessage:               60px;\n  @widthUsers:                  200px;\n  @widthMessages:               (@width - @widthUsers - 4);\n\n  @import \"sized\";\n  @import \"panels\";\n}<\/pre>\n<p>As all my CSS uses\u00a0<em>@height<\/em> and <em>@width<\/em> to manage sizable elements, I can import the Less files with new parameters for each media size and I&#8217;m done. Here&#8217;s the same for big desktops:<\/p>\n<pre class=\"lang:default decode:true\">@media (min-width: 1200px) {\n  @height:                      700px;\n  @width:                       1100px;\n  @heightMessage:               60px;\n  @widthUsers:                  300px;\n  @widthMessages:               (@width - @widthUsers - 4);\n\n  @import \"sized\";\n  @import \"panels\";\n\n}<\/pre>\n<p>So, writing a responsive CSS is not that hard, you have no excuse not to make them responsive! \ud83d\ude42 (well, at least if you&#8217;re using Juzu&#8230; If you&#8217;re using one of the usual suspects, good luck with this). Here&#8217;s what the Chat app looks like on iPhone:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-4217\" title=\"Iphone\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone.png\" alt=\"\" width=\"295\" height=\"444\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone.png 640w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-200x300.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-315x473.png 315w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-157x236.png 157w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-87x131.png 87w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-60x90.png 60w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-20x30.png 20w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Iphone-600x900.png 600w\" sizes=\"(max-width: 295px) 100vw, 295px\" \/><\/a><\/p>\n<h3>Fluid App, why not?<\/h3>\n<p>I&#8217;ll end with something a little off topic, but I think we have a final great gem here. It&#8217;s also so simple to add it into a Juzu app, so I wanted to add a note about it.<\/p>\n<p>As I wrote a Chat, the thought popped into my head: <em>hummm, it would be great to use it like any regular app&#8230;<\/em>\u00a0Luckily, I&#8217;m a Macbook Pro user, which means I&#8217;m running Max OS X. And we have a great app called <a href=\"http:\/\/fluidapp.com\" target=\"_blank\" rel=\"noopener\">Fluid App<\/a>.<\/p>\n<p>It&#8217;s great because it allows you to convert a website to an app and that&#8217;s exactly what I did in this Juzu app.<\/p>\n<p>It looks like this:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Fluidapp.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-4218\" title=\"Fluidapp\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/01\/Fluidapp.png\" alt=\"\" width=\"590\" height=\"322\" \/><\/a><\/p>\n<p>And basically, what you need to do is not that hard since Juzu allows you to do what you want, right?<br \/>\nAs I&#8217;m using extensively jQuery, which is well integrated in Juzu, I just added a few calls to make my app <em>Fluid Aware.<\/em><\/p>\n<h5>Maintain session if loaded as a Fluid App<\/h5>\n<p>We need first to maintain the session as it&#8217;s part of the real app User Experience.<\/p>\n<pre class=\"lang:default decode:true\">if (window.fluid!==undefined) {\n    chatSessionInt = clearInterval(chatSessionInt);\n    chatSessionInt = setInterval(maintainSession, chatIntervalSession);\n  }<\/pre>\n<h5>Update the notification badge<\/h5>\n<p>Then, we can add a badge on the Dock icon.<\/p>\n<pre class=\"lang:default decode:true\">window.fluid.dockBadge = totalNotif;<\/pre>\n<h5>Send growl notification if available<\/h5>\n<p>We can also send notifications in the Notification Center.<\/p>\n<pre class=\"lang:default decode:true\">if (totalNotif&gt;oldNotif &amp;&amp; profileStatus !== \"donotdisturb\" &amp;&amp; profileStatus !== \"offline\") {\n  window.fluid.showGrowlNotification({\n     title: \"eXo Chat\",\n     description: \"You have new messages\",\n     priority: 1,\n     sticky: false,\n     identifier: \"messages\"\n  });\n}<\/pre>\n<h5>Add change status menu item in the Dock app<\/h5>\n<p>Finally, we can even change our status right from the Dock \ud83d\ude42<\/p>\n<pre class=\"lang:default decode:true\">function initFluidApp() {\n if (window.fluid!==undefined) {\n   window.fluid.addDockMenuItem(\"Available\", setStatusAvailable);\n   window.fluid.addDockMenuItem(\"Away\", setStatusAway);\n   window.fluid.addDockMenuItem(\"Do not disturb\", setStatusDoNotDisturb);\n   window.fluid.addDockMenuItem(\"Invisible\", setStatusInvisible);\n }\n}\ninitFluidApp();<\/pre>\n<p>Nothing more is needed; from this point on, the application can be added as a real app in my Applications folder.<\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>So, you did it, you read these three posts to the end. I want first to give you a big thank for your reading time.<\/p>\n<p>I hope they helped you to discover this new web framework that is Juzu.<\/p>\n<p>You will find some documentation on its official website: <a href=\"http:\/\/juzuweb.org\/\" target=\"_blank\" rel=\"noopener\">http:\/\/juzuweb.org\/<\/a><br \/>\nIf you have questions about Juzu, you can go to the Google group to ask them: <a href=\"http:\/\/groups.google.com\/group\/juzu\" target=\"_blank\" rel=\"noopener\">http:\/\/groups.google.com\/group\/juzu<\/a>.<\/p>\n<p>And if you want to contribute, it&#8217;s on GitHub: <a href=\"https:\/\/github.com\/juzu\/juzu\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/juzu\/juzu<\/a>.<\/p>\n<p>Again, thousand kudos to Julien and his great work on Juzu!<\/p>\n<p>Finally, a small word about the Chat application: you want to know more or help me to build an even better Chat application? Contact me or simply fork the Chat GitHub project, I&#8217;ll be more than happy to integrate new cool ideas in the Chat (or bug fixes).<\/p>\n<p>Thus, if you want to take a deeper look at the code, it&#8217;s Open Source and available on eXo Addons Repositories: <a href=\"https:\/\/github.com\/exo-addons\/chat-application\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/exo-addons\/chat-application<\/a><em>\u00ab Again, thanks for watching and stay tuned \u2013 more things are coming, Benjamin. \u00bb<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"Today is the last of my three days on Juzu and I want to show some nice features you can find inside. If you want to start from Day 1, you can take a look in the previous posts: &#8211; Three Days with Juzu: Write a Killer App; &#8211; Juzu Day 2: Real Web Apps [&hellip;]","protected":false},"author":7,"featured_media":12746,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[699],"tags":[],"lang":"en","translations":{"en":4300},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/4300"}],"collection":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/comments?post=4300"}],"version-history":[{"count":0,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/4300\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/media?parent=4300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/categories?post=4300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/tags?post=4300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}