{"id":7950,"date":"2014-11-25T05:55:06","date_gmt":"2014-11-25T13:55:06","guid":{"rendered":"http:\/\/localhost\/exoblog\/?p=7950"},"modified":"2023-06-05T16:49:43","modified_gmt":"2023-06-05T14:49:43","slug":"developing-juzu-portlets-step-3-building-a-sexy-secret-wall","status":"publish","type":"post","link":"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-3-building-a-sexy-secret-wall\/","title":{"rendered":"Developing Juzu portlets \u2013 Step 3: Building a sexy secret wall"},"content":{"rendered":"<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-7966\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series.jpg\" alt=\"03-Juzu-tutorial-series\" width=\"650\" height=\"220\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series.jpg 650w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series-300x102.jpg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series-500x169.jpg 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series-360x122.jpg 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series-200x68.jpg 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series-100x34.jpg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-Juzu-tutorial-series-70x24.jpg 70w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><\/a><\/p>\n<p><em>Previous steps:<br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/learn-how-to-develop-great-juzu-portlets-for-exo-platform\/\">Learn how to develop great Juzu portlets for eXo Platform!<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-2-viewing-and-posting-secrets\/\">Step 2: viewing and posting secrets<\/a><br \/>\n<\/em><\/p>\n<p>In the <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-2-viewing-and-posting-secrets\/\">previous blog post<\/a>, we learned how to add some functionality to our application. We can now see a list of secrets and share new ones. It works but it\u2019s ugly&#8230; so during this blog post we will focus on the <strong>UI of JuZcret<\/strong>.<\/p>\n<p><em>We are assuming that you have already implemented <a href=\"https:\/\/www.exoplatform.com\/blog\/learn-how-to-develop-great-juzu-portlets-for-exo-platform\/\">step 1<\/a> and <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-2-viewing-and-posting-secrets\/\">step 2<\/a>. If not you can still <a href=\"https:\/\/github.com\/juzu\/portlet-tutorial\/tree\/step-2\/tutorial-juzcret\" target=\"_blank\" rel=\"noopener\">download from GitHub the source code resulting from step 2<\/a> to start this step 3.<\/em><\/p>\n<h2>Introduction<\/h2>\n<p>It\u2019s time to think a little bit about the <strong>design<\/strong> of the <strong>JuZcret application<\/strong>.<\/p>\n<p>We have to display a list of secrets that can be enhanced by an image. To do this, we will create a <strong>beautiful secret wall page<\/strong>.<\/p>\n<p>Don\u2019t forget also that we want to add new secrets. We need a new add secret page with a <strong>nice form so we can share secrets easily<\/strong>.<\/p>\n<p>During this step you will learn how to incorporate <strong>JavaScript<\/strong> and <strong>Less<\/strong> files easily in a <strong>Juzu application<\/strong>.<br \/>\n<!--more--><\/p>\n<h3>Why Less and not only CSS<\/h3>\n<p>Because Less is an <strong>amazing dynamic style sheet language<\/strong> that we love to use in eXo and the <strong>integration with Juzu<\/strong> is so <strong>easy<\/strong> that you won\u2019t have any excuses for not using it.<\/p>\n<p>Just declare the style and <strong>Juzu<\/strong> will <strong>transform it into CSS<\/strong> during compilation.<\/p>\n<p>For newbies, you just need to know that Less <strong>extends the CSS language<\/strong> with many interesting features, like variables, mixins, operations and functions. If you want more information, check out the <a href=\"https:\/\/lesscss.org\/\" target=\"_blank\" rel=\"noopener\">Less website<\/a>.<\/p>\n<h2>Create a mockup<\/h2>\n<p>This tutorial will also give you some good practice in <strong>developing a nice application<\/strong>. So, before taking the code by storm we will create a <strong>UI mockup<\/strong> (and then nicely ask the Design and UI teams for some help, which they always do with a smile ;)).<\/p>\n<p>After hours and hours of thinking, this is what I created with Balsamiq as a <strong>mockup for the secret wall<\/strong>:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-7954\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/01-mockup.png\" alt=\"01-mockup\" width=\"639\" height=\"539\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup.png 639w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-300x253.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-561x473.png 561w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-389x328.png 389w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-280x236.png 280w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-155x131.png 155w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-100x84.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/01-mockup-36x30.png 36w\" sizes=\"(max-width: 639px) 100vw, 639px\" \/><\/a><\/p>\n<p>I gave it to the <strong>Design team<\/strong> and after some <strong>tricky things<\/strong> on Photoshop this is what they give me:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed.jpg\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7955\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/02-designed.jpg\" alt=\"02-designed\" width=\"650\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed.jpg 1280w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-300x225.jpg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-1024x768.jpg 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-768x576.jpg 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-1250x938.jpg 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-631x473.jpg 631w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-437x328.jpg 437w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-315x236.jpg 315w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-175x131.jpg 175w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-100x75.jpg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/02-designed-40x30.jpg 40w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/a><\/p>\n<p>Ok, I yield!<\/p>\n<p>And for free, the add secret page:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret.jpg\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7956\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret.jpg\" alt=\"03-add-secret\" width=\"650\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret.jpg 1280w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-300x225.jpg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-1024x768.jpg 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-768x576.jpg 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-1250x938.jpg 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-631x473.jpg 631w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-437x328.jpg 437w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-315x236.jpg 315w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-175x131.jpg 175w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-100x75.jpg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/03-add-secret-40x30.jpg 40w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/a><\/p>\n<h2>Adding Less<\/h2>\n<p>Before using Less, we need to <strong>add a dependency to <span class=\"navCode\">juzu-plugins-less4j<\/span><\/strong> in the POM:<\/p>\n<pre class=\"lang:default decode:true \">&lt;dependency&gt;\n\t&lt;groupId&gt;org.juzu&lt;\/groupId&gt;\n\t&lt;artifactId&gt;juzu-plugins-less4j&lt;\/artifactId&gt;\n\t&lt;version&gt;1.0.0-cr1&lt;\/version&gt;\n&lt;\/dependency&gt;<\/pre>\n<p>The <strong>Juzu plugin Less4j<\/strong> will take care of automatically <strong>compiling<\/strong> the <strong>Less file into a CSS<\/strong> file during the Maven compilation. The only thing that we have to do is to create a new file <span class=\"navCode\">juzcret.less<\/span> in the <span class=\"navCode\">org.juzu.tutorial.assets.styles<\/span> package and then declare it in <span class=\"navCode\">package-info.java<\/span>:<\/p>\n<pre class=\"lang:default decode:true \">@Less(@Stylesheet(\"styles\/juzcret.less\"))\n@Assets(\"*\")<\/pre>\n<p>If you want to <strong>be more productive<\/strong> and create style sheets that are easily <strong>maintainable<\/strong> and <strong>extendable<\/strong>, I advise you to use <strong>Less<\/strong>. If you don\u2019t want to, then, yes, you can directly use a CSS file in a Juzu application. Add your CSS file to the <span class=\"navCode\">inorg.juzu.tutorial.assets.styles<\/span> package and declare it in <span class=\"navCode\">package-info.java<\/span> as below:<\/p>\n<pre class=\"lang:default decode:true \">@Stylesheets({@Stylesheet(value = \"styles\/my.css\")})<\/pre>\n<p>Notice the @Assets annotation. This annotation is used to <strong>declare assets<\/strong> (a style sheet or script) that will be loaded when the portlet is displayed. By setting (&#8220;*&#8221;) we declare all assets.<\/p>\n<h2>Adding jQuery<\/h2>\n<p>We will use <strong>JavaScript<\/strong> to set the width of the secret boxes randomly on the secret wall. To simplify this task, we will use the <strong>jQuery library<\/strong>.<\/p>\n<p>First create a new file <span class=\"navCode\">secret.js<\/span> in the <span class=\"navCode\">org.juzu.tutorial.assets.javascripts<\/span> package:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/04-secret-js.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-7957\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/04-secret-js.png\" alt=\"04-secret-js\" width=\"248\" height=\"118\"><\/a><\/p>\n<p>The <strong>jQuery library<\/strong> will be simply retrieved from <strong>WebJars<\/strong> thanks to the <strong>Juzu WebJars plugin<\/strong>. The Juzu WebJars plugin allows us to use an <strong>awesome JavaScript library<\/strong> easily (<a href=\"https:\/\/www.webjars.org\/\" target=\"_blank\" rel=\"noopener\">take a look here<\/a>) in our Juzu project. We just need to add the WebJars dependency to our <span class=\"navCode\">pom.xml<\/span> and declare it in <span class=\"navCode\">package-info.java<\/span>. This saves us from downloading and cloning the library file and facilitates the management of our <strong>JavaScript dependencies<\/strong>.<\/p>\n<p>In our case we want to use jQuery. We just have to add <span class=\"navCode\">juzu-plugins-webjars<\/span> and the jQuery WebJars dependency in <span class=\"navCode\">pom.xml<\/span>:<\/p>\n<pre class=\"lang:default decode:true \">&lt;dependency&gt;\n\t&lt;groupId&gt;org.juzu&lt;\/groupId&gt;\n\t&lt;artifactId&gt;juzu-plugins-webjars&lt;\/artifactId&gt;\n\t&lt;version&gt;1.0.0-cr1&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n\t&lt;groupId&gt;org.webjars&lt;\/groupId&gt;\n\t&lt;artifactId&gt;jquery&lt;\/artifactId&gt;\n\t&lt;version&gt;1.10.2&lt;\/version&gt;\n&lt;\/dependency&gt;<\/pre>\n<p>Before we use it in our application, we need to <strong>declare<\/strong> in package-info.java <strong>jQuery WebJars<\/strong> and the two assets, <span class=\"navCode\">jquery.js<\/span> and for our app <span class=\"navCode\">secret.js<\/span>, using the <strong>@Script<\/strong> annotation:<\/p>\n<pre class=\"lang:default decode:true \">@WebJars(@WebJar(\"jquery\"))\n@Scripts(\n\t{\n\t\t@Script(id = \"jquery\", value = \"jquery\/1.10.2\/jquery.js\"),\n\t\t@Script(value = \"javascripts\/secret.js\", depends = \"jquery\")\n\t}\n)\n@Assets(\"*\")<\/pre>\n<p>Notice that we declare that <span class=\"navCode\">secret.js<\/span> depends on jQuery. This ensures that <strong>jQuery is available<\/strong> to <span class=\"navCode\">secret.js<\/span> at <strong>run time<\/strong>.<\/p>\n<h2>Test Less and jQuery<\/h2>\n<p>We have now created and declared all the necessary files for implementing step 3.<\/p>\n<p>We will configure the <a href=\"https:\/\/community.exoplatform.com\/portal\/g\/:spaces:juzu\/juzu\/wiki\/Develop_Juzu_Portlet_with_JRebel\" target=\"_blank\" rel=\"noopener\">Juzu project with JRebel<\/a> if it\u2019s not done already and compile it:<\/p>\n<pre class=\"lang:default decode:true \">$ mvn clean install<\/pre>\n<p>We will replace the WAR file in the web app directory of eXo Platform with the new one just created and <strong>start the server<\/strong>:<\/p>\n<pre class=\"lang:default decode:true \">$ .\/start_eXo.sh --dev<\/pre>\n<p>Go to the JuZcret page and you will see exactly the same thing as at the end of step 2:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/05-test-less.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7958\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/05-test-less.png\" alt=\"05-test-less\" width=\"650\"><\/a><\/p>\n<p><em>Note: We are assuming that you have <strong>followed steps 1 and 2<\/strong> and have already created a JuZcret node in Platform. If not, follow step 1 to create the JuZcret node.<\/em><\/p>\n<p>Let\u2019s perform a quick test to see if the <strong>JRebel<\/strong> hot deployment is working, and test the integration of <strong>Less<\/strong> and <strong>jQuery<\/strong> also.<\/p>\n<p>Modify <span class=\"navCode\">secret.js<\/span> with:<\/p>\n<pre class=\"lang:default decode:true \">(function ($) {\n\n\t$(document).ready(function () {\n\t\twindow.alert(\"Juzu rocks !\");\n\t});\n\n})($);<\/pre>\n<p>Modify <span class=\"navCode\">juzcret.less<\/span> with:<\/p>\n<pre class=\"lang:default decode:true \">\/\/ Variables\n\/\/====================\n@textColor: red;\n\n\/\/ Common Style\n\/\/====================\n.secret-wall-list {\n\tcolor: @textColor;\n}<\/pre>\n<p>Compile:<\/p>\n<pre class=\"lang:default decode:true \">$ mvn clean compile<\/pre>\n<p>When we get a Build Successful message, we will refresh the JuZcret page:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/06-build-success.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7959\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/06-build-success.png\" alt=\"06-build-success\" width=\"650\"><\/a><\/p>\n<p><em>Note: After JRebel reloads our project, it may be possible that our portlet displays an error message instead of the expected screen. If this happens, we must recompile our project using mvn clean compile to refresh the web page. If it persists, we need to restart the server.<\/em><\/p>\n<p>jQuery <strong>displays a pop-up<\/strong> when the DOM is ready, and then the CSS resulting from our Less file will <strong>change the text color<\/strong> for the secrets to red.<\/p>\n<p>Now we are ready to implement a <strong>nice UI<\/strong> for our <strong>JuZcret<\/strong> application.<\/p>\n<h2>The secret wall<\/h2>\n<p>Open <span class=\"navCode\">secretWall.gtmpl<\/span> template and replace it with the new code below:<\/p>\n<pre class=\"lang:default decode:true \">#{param name=secretsList\/}\n\n&lt;div class=\"secret-wall-container\"&gt;\n\t&lt;div class=\"secret-wall-heading\"&gt;\n\t\t&lt;div class=\"row-fluid\"&gt;\n\t\t\t&lt;div class=\"span6\"&gt;\n\t\t\t\t&lt;h3 class=\"title\"&gt;JuZcret Portlet&lt;\/h3&gt;\n\t\t\t&lt;\/div&gt;\n\n\t\t\t&lt;div class=\"span6 text-right\"&gt;\n\t\t\t\t&lt;a class=\"btn btn-primary\" href=\"@{JuZcretApplication.addSecretForm()}\" role=\"button\"&gt;Share my secret&lt;\/a&gt;\n\t\t\t&lt;\/div&gt;\n\t\t&lt;\/div&gt;\n\t&lt;\/div&gt;\n\t&lt;ul class=\"secret-wall-list clearfix\"&gt;\n\t\t&lt;% secretsList.each { secret -&gt; %&gt;\n\t\t\t&lt;li&gt;\n\t\t\t\t&lt;div class=\"secret-image\" style=\"background-image: url('${secret.imageURL}')\"&gt;\n\t\t\t\t\t&lt;div class=\"secret-mesage\"&gt;${secret.message}&lt;\/div&gt;\n\t\t\t\t&lt;\/div&gt;\n\t\t\t&lt;\/li&gt;\n\t\t&lt;% } %&gt;\n\t&lt;\/ul&gt;\n&lt;\/div&gt;<\/pre>\n<p>Open the <span class=\"navCode\">juzcret.less<\/span> file and modify it as below:<\/p>\n<pre class=\"lang:default decode:true \">\/\/ Variables\n\/\/====================\n@heightSecretItem: 238px;\n@secretItemGutter: 6px;\n\n\/\/ Mixins\n\/\/====================\n\n\/\/ Opacity\n.opacity(@opacity) {\n\topacity: @opacity;\n\t\/\/ IE8 filter\n\t@opacity-ie: (@opacity * 100);\n\tfilter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\/\/ Common Style\n\/\/====================\n\n\/\/ Secret Wall\n.secret-wall-container {\n\tpadding: 20px 30px;\n\t.btn-primary {\n\tpadding-right: 20px;\n\tpadding-left: 20px;\n\t}\n}\n.secret-wall-container, .secret-wall-container * {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n}\n.secret-wall-heading {\n\tmargin-bottom: 10px;\n\t.btn {\n\tmargin-top: 6px;\n  }\n}\n.secret-wall-list {\n\tmargin: 0 -@secretItemGutter;\n\t&gt; li {\n\tfloat: left;\n\tpadding: @secretItemGutter;\n\twidth: 100% \/ 3;\n\t.secret-image {\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-size: cover;\n\t\tbackground-color: #000;\n\t\tposition: relative;\n\t\theight: @heightSecretItem;\n\t\twidth: 100%;\n\t\tdisplay: block;\n\t\t&amp;:before {\n\t\t\tbackground: none repeat scroll 0 0 rgba(0, 0, 0, 0.5);\n\t\t\tcontent: \"\";\n\t\t\tdisplay: block;\n\t\t\theight: 100%;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\t}\n\t.secret-mesage {\n\t\tbottom: 65px;\n\t\tcolor: #fff;\n\t\tfont-size: 20px;\n\t\tfont-weight: normal;\n\t\tleft: 25px;\n\t\tline-height: 24px;\n\t\tposition: absolute;\n\t\tright: 25px;\n\t\ttext-align: center;\n\t\ttop: 25px;\n\t}\n\t&amp;:nth-child(3n+3) {\n\t\t.popover{\n\t\t\tright: -1px;\n\t\t.arrow {\n\t\t\tleft: auto;\n\t\t\tright: 34px;\n\t\t}\n      }\n    }\n  }\n}<\/pre>\n<p>Compile:<\/p>\n<pre class=\"lang:default decode:true \">$ mvn clean compile<\/pre>\n<p>When we get a Build Successful message, we will refresh the JuZcret page and look at our new <strong>secret wall<\/strong>:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7960\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success.png\" alt=\"07-secret-wall-success\" width=\"650\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success.png 1280w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-300x188.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-1024x640.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-768x480.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-1250x781.png 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-720x450.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-500x313.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-360x225.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-200x125.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-100x63.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/07-secret-wall-success-48x30.png 48w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/a><\/p>\n<p>Notice that the title \u201c<strong>JuZcret Portlet<\/strong>\u201d in a &lt;h3&gt; tag is displayed in blue on the top left of our application even though we haven\u2019t overridden the default &lt;h3&gt; tag in <span class=\"navCode\">juzcret.less<\/span>. This is displayed in blue because the default &lt;h3&gt; tag is overridden in <span class=\"navCode\">exo-platform.css<\/span>, as <a href=\"https:\/\/github.com\/exoplatform\/ux-guidelines\/blob\/develop\/Typography\/Typography.html#S1\" target=\"_blank\" rel=\"noopener\">you can see here<\/a>. When you develop a <strong>Juzu portlet for Platform<\/strong>, you can <strong>reuse all classes<\/strong> declared in <a href=\"https:\/\/github.com\/exoplatform\/ux-guidelines\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/exoplatform\/ux-guidelines<\/a> without needing to declare them beforehand. These classes are available by default for <strong>all portlets in Platform<\/strong>.<\/p>\n<p>You can see that we still have the \u201c<strong>Juzu rocks<\/strong>\u201d pop-up! Let\u2019s modify the <strong>JavaScript<\/strong> to remove this pop-up and set the width of <strong>secret boxes randomly<\/strong>.<\/p>\n<p>Open <span class=\"navCode\">secret.js<\/span> and modify it as below:<\/p>\n<pre class=\"lang:default decode:true \">(function ($) {\n\n  $(document).ready(function () {\n\n        \/\/Var to know the number of image in the line\n        var counterImg = 0;\n        \/\/Var to know the place taken by previous image in the line\n        var totalWidthLine = 0;\n\n        function getRangeRandom(min, max) {\n            return Math.ceil(Math.random() * (max - min) + min);\n        }\n\n        function randSecretBoxWidth() {\n            var randBoxNum = getRangeRandom(23, 43);\n            \/\/Test if we are on th third image of the line\n            if (counterImg &gt;= 2) {\n                \/\/The third image of the line fill all the remaining place\n                randBoxNum = 100 - totalWidthLine;\n                \/\/counter place taken by previous image in the line set to 0\n                counterImg = 0;\n                totalWidthLine = 0;\n            }\n            else {\n                \/\/Increase counter and the place taken by previous image in the line\n                counterImg++;\n                totalWidthLine += randBoxNum;\n            }\n            \/\/Return the width of the secret box\n            return randBoxNum;\n        }\n\n        \/\/Get all secrets boxes\n        $('.secret').each(function(idx, listItem) {\n          \/\/Set a random width\n          listItem.style.width = randSecretBoxWidth() + \"%\";          \n        });\n    });\n\n})($);<\/pre>\n<p>Compile:<\/p>\n<pre class=\"lang:default decode:true \">$ mvn clean compile<\/pre>\n<p>When we get a Build Successful message, we will refresh the JuZcret page and look at our new JuZcret wall:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7961\" src=\"\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall.png\" alt=\"08-JuZcret-wall\" width=\"650\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall.png 1280w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-300x188.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-1024x640.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-768x480.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-1250x781.png 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-720x450.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-500x313.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-360x225.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-200x125.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-100x63.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/08-JuZcret-wall-48x30.png 48w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/a><\/p>\n<h2>Adding secrets<\/h2>\n<p>We have to <strong>modify<\/strong> also the ugly <strong>add secret form<\/strong>. Open the <span class=\"navCode\">addSecret.gtmpl<\/span> template and replace it with the new code below:<\/p>\n<pre class=\"lang:default decode:true \">&lt;div class=\"secret-wall-container\"&gt;\n\t&lt;div class=\"secret-wall-heading\"&gt;\n\t\t&lt;div class=\"row-fluid\"&gt;\n\t\t\t&lt;div class=\"span6\"&gt;\n\t\t\t\t&lt;h3 class=\"title\"&gt;JuZcret Portlet&lt;\/h3&gt;\n\t\t\t&lt;\/div&gt;\n\t\t\t&lt;div class=\"span6 text-right\"&gt;\n\t\t\t\t&lt;a class=\"btn btn-primary\" href=\"@{JuZcretApplication.index()}\" role=\"button\"&gt;Secret Wall&lt;\/a&gt;\n\t\t\t&lt;\/div&gt;\n\t\t&lt;\/div&gt;\n\t&lt;\/div&gt;\n\t&lt;div class=\"text-center\"&gt;\n\t\t&lt;div class=\"uiBox share-secret-box\"&gt;\n\t\t\t&lt;h4 class=\"title\"&gt;Share my secret&lt;\/h4&gt;\n\t\t\t&lt;div class=\"uiContentBox\"&gt;\n\t\t\t\t&lt;form class=\"share-secret-form\" action=\"@{JuZcretApplication.addSecret()}\" method=\"POST\" role=\"form\"&gt;\n\t\t\t\t\t&lt;div class=\"control-group\"&gt;\n\t\t\t\t\t\t&lt;label class=\"control-label\" for=\"mySecret\"&gt;My secret:&lt;\/label&gt;\n\t\t\t\t\t\t&lt;div class=\"controls\"&gt;\n\t\t\t\t\t\t\t&lt;textarea id=\"mySecret\" rows=\"3\" name=\"msg\" placeholder=\"Write your secret here\"&gt;&lt;\/textarea&gt;\n\t\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t\t&lt;div class=\"control-group\"&gt;\n\t\t\t\t\t\t&lt;label class=\"control-label\" for=\"secrImgUrl\"&gt;Image URL:&lt;\/label&gt;\n\t\t\t\t\t\t&lt;div class=\"controls\"&gt;\n\t\t\t\t\t\t\t&lt;input type=\"text\" id=\"secrImgUrl\" name=\"imgURL\" placeholder=\"\"&gt;\n\t\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t\t&lt;div class=\"control-group mgB0\"&gt;\n\t\t\t\t\t\t&lt;div class=\"controls text-center\"&gt;\n\t\t\t\t\t\t\t&lt;button type=\"submit\" class=\"btn btn-primary\"&gt;Share&lt;\/button&gt;\n\t\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t&lt;\/form&gt;\n\t\t\t&lt;\/div&gt;\n\t\t&lt;\/div&gt;\n\t&lt;\/div&gt;\n&lt;\/div&gt;<\/pre>\n<p>Notice that we are reusing default Platform UI components like <strong>uiBox<\/strong> and <strong>uiContentBox<\/strong>.<\/p>\n<p>Open the <span class=\"navCode\">juzcret.less<\/span> file and add at the end:<\/p>\n<pre class=\"lang:default decode:true \">\/\/ Add Secret\n\n.share-secret-form {\n\t.form-title {\n\t\tmargin: 0 0 10px;\n\t\ttext-shadow: none;\n\t}\n\ttextarea {\n\t\tmin-width: 271px;\n\t\tmax-width: 271px;\n\t\tmax-height: 300px;\n\t\tmargin-bottom: 10px;\n\t\tmin-height: 80px;\n\t}\n\ttextarea, input {\n\t\tmargin-bottom: 5px;\n\t}\n}\n\n.share-secret-box {\n\tdisplay: inline-block;\n\ttext-align: left;\n\tmargin-top: 20px;\n\t.title {\n\t\ttext-align: center;\n\t}\n\t.btn {\n\t\tmin-width: 78px;\n\t}\n}<\/pre>\n<p>Compile:<\/p>\n<pre class=\"lang:default decode:true \">$ mvn clean compile<\/pre>\n<p>When we get a Build Successful message, we will refresh the JuZcret page. Click on the <strong>Share my secret<\/strong> button on the top right and take a look at our <strong>new add secret form<\/strong>:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/09-new-add-secret-form.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7962\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/09-new-add-secret-form.png\" alt=\"09-new-add-secret-form\" width=\"650\"><\/a><\/p>\n<p>That\u2019s it! Play with the application and <strong>enjoy adding your personal secrets<\/strong>:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/10-add-personnal-secret.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-7963\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/11\/10-add-personnal-secret.png\" alt=\"10-add-personnal-secret\" width=\"650\"><\/a><\/p>\n<p>Here we are! As promised, we have a <strong>sexy JuZcret Portlet<\/strong>! And it\u2019s not yet finished&#8230; in the next blog post, we will add a new social feature using Ajax.<\/p>\n<p><em>The final source of step 3 is available for <a href=\"https:\/\/github.com\/juzu\/portlet-tutorial\/tree\/step-3\" target=\"_blank\" rel=\"noopener\">downloading from GitHub<\/a>.<\/em><\/p>\n<p><em>Previous and next steps:<br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/learn-how-to-develop-great-juzu-portlets-for-exo-platform\/\">Learn how to develop great Juzu portlets for eXo Platform!<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-2-viewing-and-posting-secrets\/\">Step 2: viewing and posting secrets<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-3-building-a-sexy-secret-wall\/\">Step 3: Building a sexy secret wall<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-4-adding-likes-and-comments-for-secret\/\">Step 4: adding Likes and Comments for Secret<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-5-saving-secrets-in-the-jcr\/\">Step 5: Saving Secrets in the JCR<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-6-let-the-whole-world-create-new-secrets\/\">Step 6: Let the whole world create new secrets<\/a><br \/>\n&#8211; <a href=\"https:\/\/www.exoplatform.com\/blog\/developing-juzu-portlets-step-7-finishing-the-job-properly-with-unit-test\/\">Step 7: Finishing the job properly with unit test<\/a><\/em><\/p>\n<p><em>Thanks a lot to the Design and UI teams for their contribution \ud83d\ude09<\/em><\/p>\n<p><b><a href=\"https:\/\/community.exoplatform.com\/portal\/dw\/\" target=\"_blank\" rel=\"noopener\">Join the eXo tribe<\/a> by registering for the community and get updates, tutorials, support, and access to the Platform and add-on downloads!<\/b><\/p>\n<p><!--begin adv-events--><\/p>\n<div class=\"adv-events\" style=\"background: #476fad;padding: 30px 20px;color: white\">\n<div class=\"media\">\n<div class=\"pull-right\"><a href=\"#\"><br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-6587 alignright\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2014\/02\/how-to-make-the-most-of-eXo-platform41.png\" alt=\"make-the-most-out-of-eXo-platform4\" width=\"161\" height=\"85\"><br \/>\n<\/a><\/div>\n<div class=\"media-body\">\n<h4 class=\"media-heading\">Make the most out of eXo Platform 4<\/h4>\n<p>Register to the next webinar and get a complete overview of what you can do with eXo Platform 4. <strong><a href=\"https:\/\/www.exoplatform.com\/contact-us\/\">Reserve your seat now!<\/a><\/strong><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!--end adv-events--><\/p>\n","protected":false},"excerpt":{"rendered":"Previous steps: &#8211; Learn how to develop great Juzu portlets for eXo Platform! &#8211; Step 2: viewing and posting secrets In the previous blog post, we learned how to add some functionality to our application. We can now see a list of secrets and share new ones. It works but it\u2019s ugly&#8230; so during this [&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":7950},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/7950"}],"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=7950"}],"version-history":[{"count":0,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/7950\/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=7950"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/categories?post=7950"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/tags?post=7950"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}