April 11, 2020
Estimated Post Reading Time ~

Developing Single Page Applications in AEM using AngularJS

In this article, I am going to walk you through how you can develop an extensible AngularJS application (to be specific templates and components) in AEM.

If you have a fair understanding of AngularJS and AEM then it would be easy for you to understand this tutorial else I’ll recommend gaining at least basic knowledge of both before you attempt to follow this article.

I have spent the initial few years of my career writing pure server-side applications using Java/J2EE (Servlet, JSP, Spring, different ORMs, etc.) with a little bit of JavaScript (jQuery, etc.) and I was enjoying it. From the last few years I have also started using modern JavaScript frameworks like AngularJS very heavily and it is a great experience and I am enjoying it even more and I’ll definitely recommend learning and leverage it if you can.

Let’s start with a quick overview of both AEM and AngularJS.

AngularJS
If you are in web development filed (especially front end) then I am sure you must have heard about AngularJS. It is great frameworks to build SPA - single-page applications  (remember this as you’ll need to refer this back while going through the article) and a lot of things that can be achieved very easily with minimum JavaScript code. AngularJS brings some cool features to web application development, some of them are:

1. Two Way Data-Binding
2. Templates
3. MVC (Models, Views/Partials, Controllers) and Services
4. Dependency Injection - we can create services, factories and other libraries that can be injected as and when you need it.
5. Directives – create custom HTML elements, attributes for your application.

If you are new to AngularJS or want to know more about AngularJS (which I recommend) then feel free to look at AngularJS official documentation (very soon AngularJS 2 will become popular but, in this article, I’ll be talking about AngularJS 1). Here are few links that you can refer:


AEM (Adobe Experience Manager)
AEM is a CMS developed and managed by Adobe (Adobe acquired it from communiqué a few years back). Earlier it was popular as CQ/CQ5. AEM is built on top of some of the very nice and solid frameworks in the market:

1. OSGi/Felix – allows us to develop a modular applications by developing bundles, which exposes services/components that can be referenced from other bundles. Bundles are similar to JAR files but can be deployed/un-deployed at runtime.

2. JCR/Oak – if you are new to JCR then consider this as a database/repository where everything is saved.

3. Sling – it is a framework which allows resolving incoming request to a resource on the server-side in a RESTful manner. A resource can be a JCR Node, Script, Servlet or anything else that is stored in the JCR repository.

4. Java/J2EE – I believe Java does not need any explanation :-)

AEM brings in lot of feature like:
1. Created reusable templates and components to design pagesThis is the feature that will be our focus in this article.
2. Adobe Marketing Cloud Integrations
3. Content tagging and Metadata management
4. Search
5. Manage digital assets via DAM

You can read more about AEM features at:

So, what is special about using AngularJS in AEM?

By now you must have got a basic understanding of AngularJS and AEM. If you remember 2 main features of each AngularJS and AEM (that I have highlighted above) you’ll notice that they talk about 2 different approaches to building a web page.

·      AngularJS promotes/encourages to build single page application i.e. try to consolidate views, controllers, and functionality as much as possible on one/same page so that your users don’t have a refresh page and you can load views (based on route change). With the help of $scope/$rootScope and controllers, models we achieve our functional goals. To build single page application one should know upfront about what functionality needs to be clubbed on that one page, what all are dependencies, what all controllers are needed and how (and which) scope variables, models will be used to share information across various controllers, views, directive, etc.

·      AEM promotes to break your application in smaller reusable components and templates. Various components can be combined in variety of different ways to create web page. Components don’t know about each other and AEM does not talk about how to share data between components.

And this is exactly what we are going to talk about in this article. There are many ways to use AngularJS in AEM and we’ll see one of those. Here are the steps/activities that we’ll follow in this article to develop AngularJS based AEM components:

1. Create a demo AEM TODO application (similar to http://todomvc.com/examples/angularjs) structure along with client library for AngularJS, bootstrap.
2. Create an AngularJS template.
3. Create an authorable TODO AngularJS component with controller etc. that can be dropped on any page that is created using the AngularJS template (as mentioned above).

Before you start, I would recommend downloading/cone github projects that I have created for this article so that you’ll be able to follow this article nicely. Download project from:


I have also created an AEM CRX package for this application that you can directly install in AEM. I’ll recommend to install the package directly rather than creating folders/file manually. Once you are comfortable with code base and structure you can do it from scratch later to boost your understanding.

1. Demo AEM TODO app structure & client library

Once you have installed the CRX package for this demo application you should have a structure similar to shown below. You can find CSS and JS files shown in this diagram on my github project (https://github.com/suryakand/aem-angularjs1-todo-sample).



2. Create an AngularJS template

As we saw earlier AngularJS and AEM have different recommendations for building an application (composing a page) and therefore if we want to use AngularJS with AEM then the traditional approach of developing templates and components will not work. We have to structure our template and components in different ways so that at runtime when a page is rendered it assembles JavaScript code e.g. controllers (from individual components) attach route to views and controllers etc. based on dropped components.

Look at the template (page component) under /apps/sif/components/angular/todo-sample/ng-page-todo. This template extends from “mobileapps/components/angular/ng-page” template (provided by AEM for mobile apps.  If you explore ng-todo-page template, you’ll notice that we have following structure:

Let’s look at each file one by one and understand how this structure helps us to create an AngularJS based page in AEM.

A. ng-page-todo..jsp: this is the main script file that will be invoked whenever a page is requested (created using the “ng-page-todo” template). Structure of this file is very simple and it includes 2 other scripts file head.jsp and body.jsp.

Important thing note here is the usage of ng-app attribute. Notice how angular attribute “ng-app” is initialized on the “html” tag. “ng-app” is initialized by a page property variable ${applicationName} and this will be our AngularJS application name.

B. head.jsp: this is inherited from base template “mobileapps/components/angular/ng-page” and primary use of this file is to include CSS clientlibs define in “css_clientlibs.jsp” file.

C. body.jsp: This is an important file and a lot of things are going on here so, pay attention. This will has the following functions:
  • Includes a header.jsp and footer.js where you can define common header and footer for your application.
  • Based on WCMMODE (EDIT, PREVIEW) render views. If the WCMMODE is EDIT then include template.jsp (which will render component’s markup directly) and if WCMMODE is disabled then just render tag which will be used by AngularJS application to render views. This part is very important to understand before we move to other files. The reason because of which we want to include either template.jsp or is because the way AngularJS router works. When we are in EDIT mode we don’t have access to everything that AngularJS needs to assemble and run the application (controller, services, etc.).
  • Includes JavaScript client libraries (js_clientlibs.jsp)
  • Includes “angular-app-module.js” where we define the application module and config for angular application. This file is also responsible for initializing “$routeProvider” with appropriate views and controllers with the help of scripts written in “angular-route-fragment.js.jsp”.
  • Includes “angular-app-controllers.js” file, which is responsible for assembling AngularJS controller(s) from dropped components on a page. Controller name is automatically derived from page name (by removing all special characters) 
e.g. resource.getPath().replaceAll("[^A-Za-z0-9]", "")

3. Create an authorable TODO AngularJS component

Now, let's look at the component code for the component that we’ll be dropping on the AngularJS template.

Look at the “ng-todo-list” component under /apps/sif/components/angular/todo-sample. This component extends from “mobileapps/components/angular/ng-component” (provided by AEM for mobile apps.  If you explore ng-todo-list component, you’ll notice that we have the following structure:





Let’s look at each file one by one and understand how this structure helps us to create an AngularJS based component in AEM.

A. “ng-todo-list.jsp”: this is the main script file that is responsible for rendering content and will be called first. The structure of this file is very simple and it includes only 1 script file template.jsp where we have markup for our component.

B. “overhead.jsp”: if our component needs any initialization which is independent of AngularJS then use this script file. In our case, we are not doing much here.

C. “controller.js.jsp”: This is where we’ll write AngularJS controller code. Please note that each component will have its own “controller.js.jsp”. When multiple components are places/dropped on a page/template, the script “angular-app-controllers.js” which part of template will club controller code into one controller. 

Try to look at the source (view source) of a page (created when you installed sample application). Also, look at the generated JavaScript files (todo-app.angular-app-module.js and todo-app.angular-app-controllers.js) in source code. Also, try to repeat the same process (look at view source) by disabling WCM Mode (append wcmmode=disabled as a query parameter).  e.g.  http://localhost:4502/content/en/todo-app.html?wcmmode=disabled



By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.