{"id":15822,"date":"2018-05-08T07:04:21","date_gmt":"2018-05-08T14:04:21","guid":{"rendered":"https:\/\/www.exoplatform.com\/blog\/?p=15822"},"modified":"2023-07-20T13:08:16","modified_gmt":"2023-07-20T11:08:16","slug":"use-vue-js-exo-platform","status":"publish","type":"post","link":"https:\/\/www.exoplatform.com\/blog\/use-vue-js-exo-platform\/","title":{"rendered":"How to use Vue.js in eXo Platform"},"content":{"rendered":"<p>It\u2019s pretty hard to keep up with all the new <strong>JavaScript libraries<\/strong> and <strong>frameworks<\/strong>. Three years ago, <a href=\"https:\/\/www.exoplatform.com\/?utm_source=BlogEn&amp;utm_medium=Blog&amp;utm_campaign=Content&amp;utm_content=link\">eXo<\/a> introduced <strong>AngularJS<\/strong> to boost front-end development. Now there are add-ons to show <strong>how we can use eXo Platform with AngularJS<\/strong>, like the <a href=\"https:\/\/github.com\/exo-addons\/staging-extension\" target=\"_blank\" rel=\"noopener\">staging extension<\/a>. There has also been an integration with <a href=\"https:\/\/www-upgrade.exoplatform.com\/blog\/2016\/09\/28\/getting-started-with-reactjs-and-exo-platform-portlet-development\/\" target=\"_blank\" rel=\"noopener\">ReactJS<\/a>.<\/p>\n<p>In this blog post, I\u2019d like to share my experience using <strong>VueJS with eXo<\/strong> as a front-end solution. You\u2019ll <strong>learn how to build a simple Vue.js portlet with eXo back end<\/strong>.<\/p>\n<p>You can find the <a href=\"https:\/\/github.com\/kmenzli\/exo-github-integration\" target=\"_blank\" rel=\"noopener\">sample code base in GitHub<\/a>. This is a Maven-based project, so it should be easy to import and run as-is.<\/p>\n<h2>Why Vue.js?<\/h2>\n<p>Well, simply because until now <a href=\"https:\/\/www.exoplatform.com\/?utm_source=BlogEn&amp;utm_medium=Blog&amp;utm_campaign=Content&amp;utm_content=link\">eXo<\/a> hasn\u2019t provided a ready-to-use sample with the current <strong>JavaScript<\/strong> trend known as <strong>Vue.js<\/strong>.<\/p>\n<p>No, seriously, of all the <strong>frameworks<\/strong> and <strong>libraries<\/strong> I\u2019ve worked with over the years, one thing about <strong>Vue.js<\/strong> that stands out for me is the documentation. It\u2019s very detailed and easy to follow, covering multiple-use cases and all the various options, where applicable, for each of its built-in methods.<\/p>\n<p>I decided to dive into <strong>Vue.js<\/strong> because a lot of good things are being said about it on the web (perfs, components, productivity, etc.).<\/p>\n<h2>Let\u2019s start with the basics<\/h2>\n<p><strong>AngularJS<\/strong> developers and <a href=\"https:\/\/flatirons.com\/technologies\/reactjs\/\" target=\"_blank\" rel=\"noopener\">ReactJS developers<\/a> will find that Vue.js looks like those <strong>frameworks<\/strong> (like <strong>AngularJS<\/strong> in terms of data binding and <strong>ReactJS <\/strong>in terms of directives, components and props).<\/p>\n<p>I won\u2019t describe in detail how <strong>Vue.js<\/strong> works under the hood \u2013 that\u2019s not the goal here. Instead, I\u2019ll try to give an overview of some basic concepts.<\/p>\n<p><strong>Vue.js<\/strong> uses a template file containing both the template body (HTML tags) and a script section that acts as a controller. The following example is a simple template to give you an idea of how things are structured.<\/p>\n<pre class=\"lang:default decode:true \">&lt;div id=\"app\"&gt;\r\n        {{text}}\r\n    &lt;\/div&gt;\r\n    &lt;script&gt;\r\n       var app = new Vue({\r\n            el: '#app',\r\n            data: {\r\n                text: 'Hello eXo'\r\n            },\r\n            created() {\r\n                 \/\/ API\/Service calls would go here\r\n                return {\r\n                             data: [\r\n                              {},\r\n                              {}\r\n                            ],\r\n                };\r\n         },\r\n          methods: {\r\n                  search() {\r\n                \/\/ Search method written here\r\n                },\r\n        }\r\n        })\r\n    &lt;\/script&gt;\r\n<\/pre>\n<p>The <strong>data()<\/strong> function is used to set up default data for the initial rendering of the component, and data binding within the View side is provided by the mustache pattern : <strong>{{}}<\/strong> or property <strong>v-html<\/strong>.<\/p>\n<p>The <strong>created()<\/strong> function is similar to Reacts <strong>componentWillMount<\/strong> life cycle method and is the best place to perform the init process before the rendering phase.<\/p>\n<p>The <strong>methods()<\/strong> function is where you define functions that will be used next in the View side, following the pattern <strong>@{DomEvent}=&#8221;youMethod&#8221;<\/strong>.<\/p>\n<p>This is just a taste of what\u2019s possible with Vue.js. You can see <a href=\"https:\/\/vuejs.org\/v2\/guide\/\" target=\"_blank\" rel=\"noopener\">more examples in the Vue.js documentation<\/a>.<\/p>\n<h2>Vue.js app within eXo Platform<\/h2>\n<p>To show you <strong>how to integrate Vue.js into the eXo stack<\/strong>, I decided to develop a small <strong>eXo add-on<\/strong> (a web app) to list all commits performed within a GitHub project.<\/p>\n<p>Before we can start building our app based on <strong>Vue.js<\/strong>, we need to set up a few things:<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><strong>Maven 3<\/strong>: configured and installed to build and package the add-on<\/li>\n<li style=\"font-weight: 400;\"><strong>JDK 8<\/strong>: installed<\/li>\n<li style=\"font-weight: 400;\"><strong>your favorite IDE <\/strong>(can be IntelliJ CE, Eclipse or even Visual Studio): installed<\/li>\n<li style=\"font-weight: 400;\"><strong>eXo Platform server<\/strong> (community or enterprise) 5.0<\/li>\n<\/ul>\n<h2>Develop an eXo add-on<\/h2>\n<p><strong>eXo add-ons<\/strong> are mostly web apps that we deploy on top of <a href=\"https:\/\/www.exoplatform.com\/?utm_source=BlogEn&amp;utm_medium=Blog&amp;utm_campaign=Content&amp;utm_content=link\">eXo Platform<\/a> to bring new capabilities to the platform or to customise some default configuration. To find out more, read the <a href=\"https:\/\/docs-old.exoplatform.org\/public\/index.jsp?topic=\/PLF50\/PLFDevGuide.eXoAdd-ons.PortalExtension.Howto.html\" target=\"_blank\" rel=\"noopener\"><strong>eXo documentation<\/strong> on <strong>how to create a portal extension<\/strong><\/a>.<\/p>\n<p>In the current example, I\u2019ll use an <strong>eXo extension<\/strong> with the following structure:<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><strong>services<\/strong>: Maven module to hold your API (a jar)<\/li>\n<li style=\"font-weight: 400;\"><strong>portlets<\/strong>: Maven module to hold your portlets (web app)<\/li>\n<li style=\"font-weight: 400;\"><strong>extension<\/strong>: Maven module to hold an eXo configuration (web app)<\/li>\n<li style=\"font-weight: 400;\"><strong>packaging<\/strong>: Maven module to generate an add-on (zip file)<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-15823 aligncenter\" src=\"https:\/\/www-upgrade.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1.png\" alt=\"1\" width=\"501\" height=\"254\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1.png 1112w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-300x152.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-1024x519.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-768x390.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-720x365.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-500x254.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-360x183.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-200x101.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-100x51.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/1-59x30.png 59w\" sizes=\"(max-width: 501px) 100vw, 501px\" \/><\/p>\n<p>I\u2019ll skip all the details of how to configure the extension \u2013 you can find these in the <strong>eXo documentation<\/strong>. However, to display the GitHub integration app within the home page, I used an <strong>eXo dynamic container<\/strong>, which allows us to <a href=\"https:\/\/docs.exoplatform.org\/PLF50\/PLFDevGuide.DevelopingApplications.DevelopingPortlet.Deployment.Injection.html\" class=\"broken_link\" target=\"_blank\" rel=\"noopener\">display the portlet on the homepage, as explained in the <strong>official documentation<\/strong><\/a>.<\/p>\n<h2>Develop a portlet<\/h2>\n<p>We\u2019ll focus on the integration of <strong>Vue.js 2.0<\/strong>. We assume our readers have played around with <strong>Vue.js<\/strong> and know the basics of the eXo ecosystem.<\/p>\n<h3>Wait, what is an eXo portlet?<\/h3>\n<p>A portlet is a <strong>web app<\/strong> that delivers its own resource files within a portal context. <a href=\"https:\/\/www.exoplatform.com\/?utm_source=BlogEn&amp;utm_medium=Blog&amp;utm_campaign=Content&amp;utm_content=link\">eXo Platform<\/a> allows developers to create and deploy their portlets in different flavours:<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.exoplatform.org\/PLF50\/PLFDevGuide.DevelopingApplications.DevelopingPortlet.HelloWorld.html\" class=\"broken_link\" target=\"_blank\" rel=\"noopener\"><strong>standard portlet API<\/strong>: how to create a standard portlet<\/a><\/li>\n<li><strong><a href=\"http:\/\/juzuweb.org\/\" target=\"_blank\" rel=\"noopener\">Juzu<\/a><\/strong><\/li>\n<li><strong>Spring MVC Framework<\/strong><\/li>\n<li>other possibilities<\/li>\n<\/ul>\n<p>For this example, I chose the <strong>Juzu framework<\/strong> as an <strong>MVC solution<\/strong>.<\/p>\n<h3>About the Juzu framework<\/h3>\n<p><strong>Juzu<\/strong> is a <strong>web framework<\/strong> based on MVC concepts for developing apps. We\u2019ve chosen <strong>Juzu <\/strong>because we already have a set of <strong>Juzu apps<\/strong> deployed within <a href=\"https:\/\/www.exoplatform.com\/?utm_source=BlogEn&amp;utm_medium=Blog&amp;utm_campaign=Content&amp;utm_content=link\">eXo<\/a> out of the box, but you don\u2019t need to use <strong>Juzu<\/strong> for this integration. You should be able to easily adapt this tutorial to your favourite web framework as it allows you to separate the front-end and server-side development. Our example uses Vue.js as a client-side framework and <strong>Juzu as an MVC framework<\/strong>.<\/p>\n<p>The aim here isn\u2019t to describe <strong>Juzu<\/strong>. If you want <a href=\"http:\/\/juzuweb.org\/reference\/index.html\" class=\"broken_link\" target=\"_blank\" rel=\"noopener\">to master <strong>Juzu<\/strong>, we have a guide for that<\/a>. Our goal is to explain the required steps for developers to integrate Vue.js into the <strong>Juzu portlet<\/strong>.<\/p>\n<h3>Vue.js library<\/h3>\n<p><strong>Vue.js<\/strong> claims to be a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Progressive_Web_Apps\" target=\"_blank\" rel=\"noopener\">progressive JavaScript framework<\/a>. Though the core library of <strong>Vue.js<\/strong> is quite lightweight, developers have available a large ecosystem of tools and libraries to enhance it.<\/p>\n<p>Installing Vue.js can be done in many ways:<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><strong>CDN<\/strong>:\u00a0 &lt;script src=&#8221;https:\/\/cdn.jsdelivr.net\/npm\/vue@2.5.15\/dist\/vue.js&#8221;&gt;&lt;\/script&gt;<\/li>\n<li style=\"font-weight: 400;\"><strong>NPN<\/strong>: outside the scope of this post<\/li>\n<li style=\"font-weight: 400;\"><strong>Vue-cli<\/strong>: outside the scope of this post<\/li>\n<\/ul>\n<p>In our case, we installed Vue.js as an <a href=\"https:\/\/docs.exoplatform.org\/PLF50\/PLFDevGuide.JavaScript.AMD_and_RequireJS.html\" class=\"broken_link\" target=\"_blank\" rel=\"noopener\">AMD module<\/a> using the <a href=\"https:\/\/vuejs.org\/js\/vue.min.js\" class=\"broken_link\" target=\"_blank\" rel=\"noopener\">latest stable version<\/a>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-15824 aligncenter\" src=\"https:\/\/www-upgrade.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2.png\" alt=\"2\" width=\"427\" height=\"380\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2.png 1046w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-300x267.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-1024x910.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-768x683.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-532x473.png 532w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-369x328.png 369w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-265x236.png 265w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-147x131.png 147w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-100x90.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/2-34x30.png 34w\" sizes=\"(max-width: 427px) 100vw, 427px\" \/><\/p>\n<h3>Maven module<\/h3>\n<p>You can create the project described above or you can<a href=\"https:\/\/github.com\/kmenzli\/exo-github-integration\/tree\/master\/portlets\" target=\"_blank\" rel=\"noopener\"> use this example<\/a>.<\/p>\n<h3>How to configure JavaScript modules<\/h3>\n<h4>The AMD concept<\/h4>\n<p><strong>AMD <\/strong>(or asynchronous module definition) is a <strong>JavaScript<\/strong> pattern that defines the way a library is loaded as a module, as opposed to a global object, that is available only to another module that \u2018requires\u2019 it. <strong>AMD <\/strong>is often used in eXo to improve client-side perfs. <a href=\"https:\/\/docs.exoplatform.org\/PLF50\/PLFDevGuide.JavaScript.AMD_and_RequireJS.html\" class=\"broken_link\" target=\"_blank\" rel=\"noopener\">Read more about <strong>AMD <\/strong>in this document<\/a>.<\/p>\n<h4>Use Vue.js as a module<\/h4>\n<p>To use <strong>Vue.js library<\/strong>, developers have to add the following configuration to <strong>gatein-resources.xml<\/strong>:<\/p>\n<pre class=\"lang:default decode:true \">&lt;module&gt;\r\n        &lt;name&gt;vuejs&lt;\/name&gt;\r\n        &lt;as&gt;vuejs&lt;\/as&gt;\r\n        &lt;script&gt;\r\n            &lt;path&gt;\/javascript\/vue.js&lt;\/path&gt;\r\n        &lt;\/script&gt;\r\n    &lt;\/module&gt;\r\n<\/pre>\n<p>Easy, isn\u2019t it?<\/p>\n<h4>Add a Vue.js module as a dependency to your portlet<\/h4>\n<p>As seen above, <strong>Vue.js<\/strong> is already configured as a module within eXo Platform. To use it in an app, developers need to declare it as a <strong>dependency<\/strong> in the same <strong>gatein-resources.xml<\/strong>:<\/p>\n<pre class=\"lang:default decode:true \">&lt;portlet&gt;\r\n       &lt;name&gt;GithubIntegrationControllerApplication&lt;\/name&gt;\r\n       &lt;module&gt;\r\n           &lt;depends&gt;\r\n               &lt;module&gt;githubIntegration&lt;\/module&gt;\r\n           &lt;\/depends&gt;\r\n       &lt;\/module&gt;\r\n   &lt;\/portlet&gt;\r\n   &lt;module&gt;\r\n       &lt;name&gt;githubIntegration&lt;\/name&gt;\r\n       &lt;script&gt;\r\n           &lt;path&gt;\/javascript\/github.js&lt;\/path&gt;\r\n       &lt;\/script&gt;\r\n       &lt;depends&gt;\r\n           &lt;module&gt;vuejs&lt;\/module&gt;\r\n       &lt;\/depends&gt;\r\n       &lt;depends&gt;\r\n           &lt;module&gt;juzu-ajax&lt;\/module&gt;\r\n       &lt;\/depends&gt;\r\n       &lt;depends&gt;\r\n           &lt;module&gt;jquery&lt;\/module&gt;\r\n           &lt;as&gt;jQuery&lt;\/as&gt;\r\n       &lt;\/depends&gt;\r\n   &lt;\/module&gt;<\/pre>\n<p>As you may have noticed, the configuration above brings a set of <strong>javascript libraries<\/strong> and injects them as <strong>AMD<\/strong> within our application when it is rendered by the portal:<\/p>\n<ul>\n<li><strong>juzu-ajax : Module provided out of the box by Juzu Framework to enable communication between client side (javascript) and server side (business layer)<\/strong><\/li>\n<\/ul>\n<ul>\n<li>jquery : Module provided out of the box by portal project to enable jquery framework<\/li>\n<\/ul>\n<h4>Vue.js in action<\/h4>\n<p><strong>Using Vue.js<\/strong> within your code implies managing a <strong>Vue<\/strong> object instance through several phases, including observing data, initialising events and rendering. You can register life cycle hooks that will be employed in specific phases.<\/p>\n<p>In the next example, we will use <strong>Vue.js<\/strong> to monitor a Git repository and then display the five most recent commits for each branch.<\/p>\n<pre class=\"lang:default decode:true \">(function ($) {\r\n\r\n var apiURL = 'https:\/\/api.github.com\/repos\/kmenzli\/sphinx-poc\/commits?per_page=3&amp;sha='\r\n\r\n \/**\r\n   * Actual demo\r\n   *\/\r\n\r\n var demo = new Vue({\r\n\r\n    el: '#github',\r\n\r\n    data: {\r\n      branches: ['master', 'stable\/4.4.x'],\r\n      currentBranch: 'master',\r\n      commits: null\r\n    },\r\n\r\n    created: function () {\r\n     this.usingJuzu()\r\n    },\r\n\r\n    watch: {\r\n      currentBranch: 'usingJuzu'\r\n    },\r\n\r\n    filters: {\r\n      truncate: function (v) {\r\n       var newline = v.indexOf('\\n')\r\n       return newline &gt; 0 ? v.slice(0, newline) : v\r\n      },\r\n      formatDate: function (v) {\r\n       return v.replace(\/T|Z\/g, ' ')\r\n      }\r\n    },\r\n\r\n    methods: {\r\n      fetchData: function () {\r\n       var xhr = new XMLHttpRequest()\r\n       var self = this\r\n        xhr.open('GET', apiURL + self.currentBranch)\r\n        xhr.onload = function () {\r\n          self.commits = JSON.parse(xhr.responseText)\r\n          console.log(self.commits[0].html_url)\r\n        }\r\n        xhr.send()\r\n      },\r\n      usingJuzu: function () {\r\n\r\n       var $githubDiv = $(\"#github\");\r\n       var createURL = $githubDiv.jzURL(\"GithubIntegrationController.create\");\r\n        $.ajax({\r\n          type: 'POST',\r\n          url: createURL,\r\n          success: function (data) {\r\n           \/\/ Reload project tree;\r\n           this.commits = []\r\n            console.log(data.id);\r\n          },\r\n          error: function (xhr) {\r\n           if (xhr.status &gt;= 400) {\r\n              console.log(xhr.responseText);\r\n            } else {\r\n              alert('error while create new project. Please try again.');\r\n            }\r\n          }\r\n        });\r\n\r\n      }\r\n    }\r\n  })\r\n})(jQuery);\r\n<\/pre>\n<p><strong>Note<\/strong>: developer should adapt the <strong>javascript <\/strong>variable <strong>apiURL<\/strong> to his own github repository<\/p>\n<h4>Server-side rendering<\/h4>\n<p>The <a href=\"https:\/\/github.com\/kmenzli\/exo-github-integration\/blob\/master\/portlets\/src\/main\/java\/org\/exoplatform\/addons\/portlets\/github\/templates\/index.gtmpl\" target=\"_blank\" rel=\"noopener\">code for the main page is in the index.gtmpl file in the templates folder of the portlet<\/a>. Here it is:<\/p>\n<pre class=\"lang:default decode:true\">&lt;div id=\"github\"&gt;\r\n &lt;div class=\"UIGadgetThemes uiBox uiGithubIntegration\"&gt;\r\n   &lt;h6 class=\"gadgetTitle title center\"&gt;Github Commit's history&lt;\/h6&gt;\r\n   &lt;div class=\"content row-fluid\"&gt;\r\n   &lt;template v-for=\"branch in branches\"&gt;\r\n     &lt;span class=\"uiRadio\"&gt;\r\n       &lt;input type=\"radio\" :id=\"branch\" :value=\"branch\" name=\"optionsRadios\" v-model=\"currentBranch\"&gt;\r\n       &lt;span&gt;&lt;\/span&gt;\r\n       &lt;label class=\"radioLabel\" :for=\"branch\"&gt;{{ branch }}&lt;\/label&gt;\r\n     &lt;\/span&gt;\r\n   &lt;\/template&gt;\r\n\r\n   &lt;div class=\"clearfix\" \/&gt;\r\n   &lt;p&gt;\r\n     &lt;span&gt;Current branch : &lt;\/span&gt;\r\n     &lt;strong&gt;{{ currentBranch }}&lt;\/strong&gt;\r\n   &lt;\/p&gt;\r\n\r\n\r\n   &lt;div class=\"clearfix\" \/&gt;\r\n   &lt;div class=\"list-group\" v-for=\"record in commits\"&gt;\r\n     &lt;a :href=\"record.html_url\" class=\"list-group-item active\"&gt;\r\n       &lt;h4 class=\"list-group-item-heading\"&gt;{{ record.sha.slice(0, 7) }} - {{ record.commit.message | truncate }}&lt;\/h4&gt;\r\n       &lt;p class=\"list-group-item-text\"&gt;\r\n         &lt;span class=\"author\"&gt;\r\n           &lt;a :href=\"record.author.html_url\" target=\"_blank\"&gt;{{ record.commit.author.name }}&lt;\/a&gt;\r\n         &lt;\/span&gt;\r\n          at\r\n         &lt;span class=\"date\"&gt;{{ record.commit.author.date | formatDate }}&lt;\/span&gt;\r\n       &lt;\/p&gt;\r\n     &lt;\/a&gt;\r\n   &lt;\/div&gt;\r\n &lt;\/div&gt;\r\n &lt;\/div&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">When the browser creates a Vue instance represented by the div with the GitHub identifier, it loads the HTML and performs the binding between the model and the view.<\/span><\/p>\n<p>Bravo! You\u2019ve successfully bootstrapped your own <strong>Vue.js<\/strong> app. Keep at it!<\/p>\n<h2>Deploying your add-on<\/h2>\n<h3>Build process<\/h3>\n<p>The first step is to build your project, which means generating required artefacts to roll up into the <strong>eXo server<\/strong>. Building an <strong>eXo add-on<\/strong> is pretty simple. From the root folder, build your project by running the following Maven command line:<\/p>\n<p><strong><i>mvn clean install <\/i><\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-15825\" src=\"https:\/\/www-upgrade.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3.png\" alt=\"3\" width=\"1600\" height=\"519\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3.png 1600w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-300x97.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-1024x332.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-768x249.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-1536x498.png 1536w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-1250x405.png 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-720x234.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-500x162.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-360x117.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-200x65.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-100x32.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/3-70x23.png 70w\" sizes=\"(max-width: 1600px) 100vw, 1600px\" \/><\/p>\n<p>The expected output is a zip file called <strong>github-integration.zip<\/strong>:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-15826\" src=\"https:\/\/www-upgrade.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4.png\" alt=\"4\" width=\"611\" height=\"323\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4.png 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-300x158.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-1024x541.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-768x406.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-720x380.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-500x264.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-360x190.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-200x106.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-100x53.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/4-57x30.png 57w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><\/p>\n<h4>Deploy artefacts into the eXo server<\/h4>\n<p>Once the build process is complete, you need to deploy all the generated artefacts in the corresponding folders of the <strong>eXo Tomcat server<\/strong>. The first step is to unpack <strong>github-integration.zip <\/strong>somewhere on your file system, then copy and paste its contents into the following location:<\/p>\n<ul>\n<li style=\"font-weight: 400;\">github-integration\/lib into eXoPlatform\/lib<\/li>\n<li style=\"font-weight: 400;\">github-integration\/webapps into eXoPlatform\/webapps<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-15827\" src=\"https:\/\/www-upgrade.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5.png\" alt=\"5\" width=\"1600\" height=\"570\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5.png 1600w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-300x107.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-1024x365.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-768x274.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-1536x547.png 1536w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-1250x445.png 1250w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-720x257.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-500x178.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-360x128.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-200x71.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-100x36.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/5-70x25.png 70w\" sizes=\"(max-width: 1600px) 100vw, 1600px\" \/><\/p>\n<h2>Running your add-on<\/h2>\n<p>Start the server by running the following command line on the root folder of your <a href=\"https:\/\/www.exoplatform.com\/?utm_source=BlogEn&amp;utm_medium=Blog&amp;utm_campaign=Content&amp;utm_content=link\">eXo Platform<\/a> instance (depending on your operating system):<\/p>\n<pre class=\"lang:default decode:true\">.\/start_eXo.sh<\/pre>\n<h2>Playing around<\/h2>\n<ol>\n<li style=\"font-weight: 400;\">Connect as a standard user.<\/li>\n<li style=\"font-weight: 400;\">At the bottom of the home page, you\u2019ll see the github-integration app.<\/li>\n<li style=\"font-weight: 400;\">You can switch between branches and list commits by branch.<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-15828\" src=\"https:\/\/www-upgrade.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6.png\" alt=\"6\" width=\"1220\" height=\"648\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6.png 1220w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-300x159.png 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-1024x544.png 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-768x408.png 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-720x382.png 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-500x266.png 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-360x191.png 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-200x106.png 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-100x53.png 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2018\/05\/6-56x30.png 56w\" sizes=\"(max-width: 1220px) 100vw, 1220px\" \/><\/p>\n<p>In upcoming posts, I\u2019ll show you how to use <strong>Vue.js<\/strong> life cycles to build more reactive portlets \u2013 so stay tuned.<\/p>\n<div>\n<div class=\"adv-events\" style=\"background: #476fad; padding: 30px 20px; color: white;\">\n<div class=\"media\">\n<div class=\"pull-right\"><a title=\"eXo Community\" href=\"https:\/\/community.exoplatform.com\/portal\/dw\/\" target=\"_blank\" rel=\"noopener\"><br \/>\n<img decoding=\"async\" class=\"size-full wp-image-6587 alignright\" style=\"border: none;\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2016\/02\/tribe.png\" alt=\"Join The eXo Tribe\" height=\"120px\" \/><br \/>\n<\/a><\/div>\n<div class=\"media-body\">\n<div class=\"media-heading\"><a title=\"eXo Tribe\" href=\"https:\/\/community.exoplatform.com\/portal\/dw\/\" target=\"_blank\" rel=\"noopener\">Join The eXo Tribe<\/a><\/div>\n<p><a href=\"https:\/\/community.exoplatform.com\/portal\/dw\/\" target=\"_blank\" rel=\"noopener\"><br \/>\nRegister for our Community to Get updates, tutorials, support, and access to the Platform and add-on downloads. <strong>Sign in Now!<\/strong><br \/>\n<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"It\u2019s pretty hard to keep up with all the new JavaScript libraries and frameworks. Three years ago, eXo introduced AngularJS to boost front-end development. Now there are add-ons to show how we can use eXo Platform with AngularJS, like the staging extension. There has also been an integration with ReactJS. In this blog post, I\u2019d [&hellip;]","protected":false},"author":72,"featured_media":15829,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":[],"categories":[819],"tags":[606,711,827],"lang":"en","translations":{"en":15822},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/15822"}],"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\/72"}],"replies":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/comments?post=15822"}],"version-history":[{"count":0,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/15822\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/media\/15829"}],"wp:attachment":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/media?parent=15822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/categories?post=15822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/tags?post=15822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}