11 mins
Jun 26, 2024
As techies, we always try to find out how we can use multiple collaborated technologies so that we can utilize the maximum strengths of different technologies, overcome their individual limitations and use them in creating the most suitable solution. During our research work for technologies, we have found that an Angular 2.0 application integrated with Liferay DXP offers a unique combination.
AngularJS had already been much popular among developers and enhancements of Angular 2.0 have made it even more preferred to create speedy, rich and effective applications. As we know, Angular 2.0 also requires third party tools to leverage security features, Authorization/Authentication etc. With its OOTB functionalities, Liferay DXP can be proved an ideal solution to be used with Angular 2.0 because of many reasons. Few are listed below:
In this blog, step by step we will create a simple “Hello World” Angular 2.0 App in Liferay DXP Theme. We have classified the blog in three easy steps for simplified understanding.
Explore our expertise in React Native App Development Services
Prerequisite:
You need to have the basic idea about creating a simple Angular application
If you are too new to Angular, please find the basic understanding.
You need to have primary knowledge about creating a theme for Liferay DXP
If you are not familiar with Liferay theme creation, please
find the primary knowledge at Step by Step Guide to Create Theme for Liferay DXP.
Once you are ready with essential information, we are ready to start our actual work.
Explore our expertise in Full Stack Development Services
Create new Liferay Theme “hello-world-theme” and deploy it
Adding Angular to Liferay theme
1. Now, let’s add Angular files to Liferay theme
Your “src” folder will look like image shown below.2. Load Node Modules for Angular dependencies
{ “name”: “angular-quickstart”, “version”: “1.0.0”, “scripts”: { “start”: “npm run lite”, “lite”: “lite-server” }, “license”: “MIT”, “dependencies”: { “@angular/common”: “~2.4.0”, “@angular/compiler”: “~2.4.0”, “@angular/core”: “~2.4.0”, “@angular/forms”: “~2.4.0”, “@angular/http”: “~2.4.0”, “@angular/platform-browser”: “~2.4.0”, “@angular/platform-browser-dynamic”: “~2.4.0”, “@angular/router”: “~3.4.0”, “@angular/upgrade”: “~2.4.0”, “angular-in-memory-web-api”: “~0.3.1”, “core-js”: “^2.4.1”, “rxjs”: “5.0.1”, “zone.js”: “^0.8.4” }, “devDependencies”: { “concurrently”: “^3.0.0”, “lite-server”: “^2.2.2” } }
Now you able to see “node_modules” folder created inside “src” folder.
You have all dependent modules installed in your theme > src > node_modules folder.
3. Create “App” folder inside “src” folder and create two files app.component.js and app.module.js.
Grab code and put it in app.component.js file:
(function(app) { app.AppComponent = ng.core.Component({ selector: ‘my-app’, //Application Name template: ‘<h1>Hello World : Angular 2 App</h1>’ //Template you can use <TemplateURL> also }) .Class({ constructor: function() {} }); })(window.app || (window.app = {}));
And put below code in app.module.js file:
(function(app) { app.AppModule = ng.core.NgModule({ imports: [ ng.platformBrowser.BrowserModule ], declarations: [ app.AppComponent ], bootstrap: [ app.AppComponent ] }) .Class({ constructor: function() {} }); })(window.app || (window.app = {}));
4. Now we have some files in “App” and “node_modules” folder and the complexity is how to call files from the folders because by default Liferay provides access only to CSS, JS and Images folder.
<#assign appPath = “${theme_display.getPortalURL()}${theme_display.getPathThemeRoot()}/app”/> <#assign nodeModules = “${theme_display.getPortalURL()}${theme_display.getPathThemeRoot()}/node_modules”/>
Now we have ${appPath} and ${nodeModules} path available to access files inside these folders.
5. Load libraries and app files into theme. Search for <!– inject:js–><!– endinject –> text in portal_normal.ftl.
Put the below given code between <!– inject:js–><!– endinject –> comments.
<!– inject:js–> <!—1. Liferay Custom module loader –> <script> define._amd = define.amd; define.amd = false; </script> <!– 2. Load common libraries –> <script src=”${nodeModules}/core-js/client/shim.min.js”></script> <script src=”${nodeModules}/zone.js/dist/zone.js”></script> <script src=”${nodeModules}/rxjs/bundles/Rx.js”></script> <script src=”${nodeModules}/@angular/core/bundles/core.umd.js”></script> <script src=”${nodeModules}/@angular/common/bundles/common.umd.js”></script> <script src=”${nodeModules}/@angular/compiler/bundles/compiler.umd.js”></script> <script src=”${nodeModules}/@angular/platform-browser/bundles/platform-browser.umd.js”></script> <script src=”${nodeModules}/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js”></script> <!– 3. Load App ‘modules’ –> <script src=’${appPath}/app.component.js’></script> <script src=’${appPath}/app.module.js’></script> <script> (function(app) { document.addEventListener(‘DOMContentLoaded’, function() { ng.platformBrowserDynamic .platformBrowserDynamic() .bootstrapModule(app.AppModule); }); })(window.app || (window.app = {})); </script> <script> define.amd = define._amd; </script> <!– endinject –>
You will be able to see the files being loaded from ${nodeModules} and ${appPath} folder.
6. It is time to load your angular app now
If you observe, your complete portal_normal.ftl code will look as shown below.
<html class=”${root_css_class}” dir=”<@liferay.language key=”lang.dir” />” lang=”${w3c_language_id}”> <head> <title>${the_title} – ${company_name}</title> <meta content=”initial-scale=1.0, width=device-width” name=”viewport” /> <@liferay_util[“include”] page=top_head_include /> <!– appPath Variable : to load components and module files –> <#assign appPath = “${theme_display.getPortalURL()}${theme_display.getPathThemeRoot()}/app”/> <!– nodeModules Variable : to load dependant node module files –> <#assign nodeModules = “${theme_display.getPortalURL()}${theme_display.getPathThemeRoot()}/node_modules”/> </head> <body class=”${css_class}”> <@liferay_ui[“quick-access”] contentId=”#main-content” /> <@liferay_util[“include”] page=body_top_include /> <@liferay.control_menu /> <div class=”container-fluid” id=”wrapper”> <header id=”banner” role=”banner”> <div id=”heading”> <h1 class=”site-title”> <a class=”${logo_css_class}” href=”${site_default_url}” title=”<@liferay.language_format arguments=”${site_name}” key=”go-to-x” />”> <img alt=”${logo_description}” height=”${site_logo_height}” src=”${site_logo}” width=”${site_logo_width}” /> </a> <#if show_site_name> <span class=”site-name” title=”<@liferay.language_format arguments=”${site_name}” key=”go-to-x” />”> ${site_name} </span> </#if> </h1> </div> <#if !is_signed_in> <a data-redirect=”${is_login_redirect_required?string}” href=”${sign_in_url}” id=”sign-in” rel=”nofollow”>${sign_in_text}</a> </#if> <#if has_navigation && is_setup_complete> <#include “${full_templates_path}/navigation.ftl” /> </#if> </header> <section id=”content”> <!– Load your Angular App –> <my-app>Loading…</my-app> <#if selectable> <@liferay_util[“include”] page=content_include /> <#else> ${portletDisplay.recycle()} ${portletDisplay.setTitle(the_title)} <@liferay_theme[“wrap-portlet”] page=”portlet.ftl”> <@liferay_util[“include”] page=content_include /> </@> </#if> </section> <footer id=”footer” role=”contentinfo”> <p class=”powered-by”> <@liferay.language key=”powered-by” /> <a href=”http://www.liferay.com” rel=”external”>Liferay</a> </p> </footer> </div> <@liferay_util[“include”] page=body_bottom_include /> <@liferay_util[“include”] page=bottom_include /> <!– inject:js–> <script> define._amd = define.amd; define.amd = false; </script> <!– Load common libraries –> <script src=”${nodeModules}/core-js/client/shim.min.js”></script> <script src=”${nodeModules}/zone.js/dist/zone.js”></script> <script src=”${nodeModules}/rxjs/bundles/Rx.js”></script> <!– Load Angular Dependencies –> <script src=”${nodeModules}/@angular/core/bundles/core.umd.js”></script> <script src=”${nodeModules}/@angular/common/bundles/common.umd.js”></script> <script src=”${nodeModules}/@angular/compiler/bundles/compiler.umd.js”></script> <script src=”${nodeModules}/@angular/platform-browser/bundles/platform-browser.umd.js”></script> <script src=”${nodeModules}/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js”></script> <!– Load App ‘modules’ –> <script src=’${appPath}/app.component.js’></script> <script src=’${appPath}/app.module.js’></script> <!– Calling our Angular App to page –> <script> (function(app) { document.addEventListener(‘DOMContentLoaded’, function() { ng.platformBrowserDynamic .platformBrowserDynamic() .bootstrapModule(app.AppModule); }); })(window.app || (window.app = {})); </script> <script> define.amd = define._amd; </script> <!– endinject –> </body> </html>
Once all above actions are completed, it’s time to build theme and run your App.
And that’s done. Your first Angular 2.0 App in Liferay DXP is ready now.
Liferay DXP can make your Angular 2.0 application much secured. Its OOTB features and functionalities save you from lot of code work and they easily can be integrated with Angular 2.0 app. It will offer quick and rich user experience to the user. As a matter of fact, Liferay DXP has got potential to offer robust and highly scalable technology solutions. If researched and executed well, it can empower other technologies as well.
If you longing to learn more, please mail us your query.
Explore our expertise in Java Development Services
We are deeply committed to translate your product vision into product value with our dedication to delivering nothing less than excellence.
5432 Geary Blvd, Unit #527 San Francisco, CA 94121 United States
14080 Jedediah Court, Grass Valley, CA 95945 United States
6d-7398 Yonge St,1318 Thornhill, Ontario, Canada, L4J8J2
Hohrainstrasse 16, 79787 Lauchringen, Germany
Place Grand Saint Jean 1, 1003 Lausanne, Switzerland
Karlavägen 18, 114 31 Stockholm, Sweden
5th floor, Bloukrans Building, Lynnwood Road, Pretoria, Gauteng, 0081, South Africa
12th & 13th Floor, B Square-1, Bopal – Ambli Road, Ahmedabad – 380054
B/305A, 3rd Floor, Kanakia Wallstreet, Andheri (East), Mumbai, India