Developing Single Page Applications in AEM using AngularJS
In this article I am going to walk you through how you can
develop extensible AngularJS application (to be specific templates and
component) in AEM.
If you have fair understanding of AngularJS and AEM then it
would be easy for you understand this tutorial else I’ll recommend to gain at
least basic knowledge of both before you attempt to follow this article.
I have spent initial few years of my career to write pure
server side application using Java/J2EE (Servlet, JSP, Spring, different ORMs
etc.) with little bit of JavaScript (jQuery etc.) and I was enjoying it. From
last few years I have also started using modern JavaScript framework like
AngularJS very heavily and it is a great experience and I am enjoying it even
more and I’ll definitely recommend to learn 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 (specially front end)
then I am sure you must have heard about AngularJS. It is a great frame works
to build SPA - ingle
page applications (remember this as you’ll need to refer this
back while going through article) and lot 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é few years back). Earlier it was popular as CQ/CQ5. AEM is
built on top of some of very nice and solid frameworks in market:
1. OSGi/Felix – allows us to develop modular application 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 to resolve
incoming request to a resource on server side in RESTful manner. A resource can
be a JCR Node, Script, Servlet or anything else that is stored in 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 pages.
This is the feature that will be our
focus in this article.
2. Adobe Marketing Cloud Integrations
3. Content tagging and Meta data 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 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 of
building 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 refresh page
and you can load views (based on route change). With 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 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 AngularJS
template (as mentioned above).
Before you start, I would recommend to download/cone github
project that I have created for this article so that you’ll be bale 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 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 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 traditional approach of developing templates and
components will not work. We have to structure our template and components in
different way 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”
templae (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 “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 usage of ng-app attribute.
Notice how angular attribute “ng-app” is initialized on “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 lot of things are going on here so, pay attention.
This will has 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 application (controller, services etc.). - Includes JavaScript client libraries (js_clientlibs.jsp)
- Includes “angular-app-module.js” where we define 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, lets look at the component code for the component that
we’ll be dropping on 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 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. 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 same
process (look at view source) by disabling WCM Mode (append wcmmode=disabled as query
parameter). e.g. http://localhost:4502/content/en/todo-app.html?wcmmode=disabled
I have tried to keep this article simple to you a head start
and information about how you can build AngularJS applications in AEM. If find
something that can be improved as part of this application or in sample code
feel free to leave a comment or write directly to me and I’ll try to work on
that.
Thanks for reading!!!
Comments
Could you please let me know how to edit partial page components in Master page for Single Page Applications?
Could you please let me know how to edit/author components in Master Page in SPA.
COuld you please let me know how to edit/author CQ components in Master Page of SPA.
Very nice post. Could you please provide the github repository?
Very nice article. Could you please provide the source code?
Thanks
Could you please clarify why we need angular in AEM ?
submit is just excellent and i can suppose you’re knowledgeable in this subject.
Very Nice Post really expalined good information and Please keep updating us..... Thanks
Can you please post the files in the git repository.