Up and Running: AEM Apps with PhoneGap Enterprise

This tutorial will walk you through the process of developing a mobile app called We-Shop. Along the way as new concepts in AEM apps are introduced the corresponding documentation is provided for reference. We-Shop is an in-store shopper concierge app that provides users with relevant content for in-store and out of store use. This guide is targeted for a Mac, however AEM apps can be developed on Mac, PC and Linux.

Features of AEM Apps

(Insert AEM Mobile marketing features)

Intended Audience

Developers that need to get up and running with AEM mobile app development will benefit from following along with this guide. This guide is intended for developers that have experience working with HTML, JavaScript and CSS. Knowledge of AngularJS and the Ionic framework will be beneficial.

Table of Contents

Overview of AEM Apps with PhoneGap Enterprise

Setting up your dev environment

Setting up your first PhoneGap Enterprise mobile app

Running the app on the iOS Simulator

Running your app on a mobile device using the PhoneGap Enterprise App

Setting up Brackets for Component Development

Creating a reusable component in AEM

Structure of a PGE app

Adding the PhoneGap app-version plugin to your project

Creating a Component

Intro to Templates: Adding a navigation item to the Hamburger Menu

Creating a Tab Bar for Navigation

Creating a Template Page

Customizing the navigation header and tab bar

Creating a Reusable Grid Layout Component

Adding 3rd Party Javascript Libraries to your PGE App

Creating a product card

Publishing changes to the app using Over the Air Updates (OTA)

Next Steps

About

Overview of AEM Apps with PhoneGap Enterprise (PGE):

AEM is built using Apache Sling, a web application framework

PhoneGap: is a framework that allows you to create mobile apps using standardized web APIs and provides you with access to mobile hardware such as the camera, geolocation and accelerometer.

Apache Cordova: is a platform for building native mobile applications using HTML, CSS and JavaScript.

The following frameworks/tools are used in the Starter Kit package that is used to create a ‘vanilla’ PGE app, but are not required for AEM mobile app development.

Ionic is a popular mobile front-end framework which can be leveraged by AEM Apps projects to give the mobile app a modern UI and also easily integrate common mobile design patterns such as table views and tab bars. Although the starterkit used to create a ‘vanilla’ PhoneGap Enterprise app uses Ionic and this tutorial relies heavily on Ionic’s CSS styling, it is possible to use other JavaScript frameworks as the foundation of your cross platform app.

AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML's syntax to express your application's components clearly and succinctly. The Ionic Framework also relies on AngularJS, making it a good fit for AEM App development.

Apache Maven manages the project build and installs dependencies for the project.

Prerequisites:

AEM 6.1 is restricted to customers and can be downloaded here

There is a .jar file for running AEM locally and a .war for deploying AEM on a server.

Download the .jar file and double click it to run AEM. The initial run will extract all the

necessary files for AEM, so future startup times will be much faster.

Make sure your license.properties file is in the same folder as your .jar file.

Xcode version >= 6.3.1 available.

Node.js >= 0.12.x available

Phonegap CLI version == 5.1.1

Android SDK

Brackets

Setting up your dev environment:

Install Java. On newer Macs javac does not come preinstalled, so download and install JDK from here.

Add java to your .bash_profile

        Open terminal and enter:

touch ~/.bash_profile; open ~/.bash_profile

        In the text file add:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home

        Make sure to change ‘jdk1.8.0_45’ to the version of java you installed

        Save the text file and run the Terminal command:

source ~/.bash_profile

        To make sure java is running properly enter the commands:

        java -version

        javac -version

Install Brew (a package manager for Mac):

        type into terminal:

        ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

Install Maven, (Maven 3.3.3 does not work with AEM 6.1)

Run the following commands in terminal(you many need to restart Terminal after installing brew):

        brew install homebrew/versions/maven32

brew pin homebrew/versions/maven32

Add maven to your path by opening your .bash_profile again and adding the following line:

        export PATH="$PATH:$M2_HOME/bin"

Setting up your first PhoneGap Enterprise mobile app:

To create a new app we will be using the AEM-phonegap-starter-kit. The starter kit is based on the multimodule-content-package-archetype (with the bundle removed for simplicity), so it contains the same helpful profiles and properties to build and deploy your project with Maven. Download the zip of the github project to get started.

  1. Unzip the project, and rename it to aem-phonegap-starter-kit.

Notice the two folders content-author, and content-dev. The content-dev folder contains the the templates and components that a developer creates and manages. The content-author folder contains instances of the components and templates that are created and managed through the AEM Authoring Panel.

  1. Run your local copy of AEM 6.1 and login with both the username and password as admin
  2. Open terminal and navigate to the root the phonegap starterkit:

cd ~/downloads/aem-phonegap-starter-kit

  1. To customize the name and company of the app run the script customize.sh. This script modifies the directory structure, XML and JSON files used to create an app in AEM. Throughout this documentation you will see a reference to [company_name] and [app_name] which are set here. Run the customize-app.sh script by providing the company name first, and the app name. In our case will name the app We-Shop with the company name Adobe:

./customize-app.sh Adobe We-Shop

  1. Install the app using maven:

mvn -PautoInstallPackage clean install

If the build fails try running the following command and then try and install again:

mvn -Dcrx.host=otherhost -Dcrx.port=4502 clean

Congrats! You have your first AEM app successfully setup and ready for modification. Go ahead and navigate to the Apps admin console and you should see your new app.

*Note your instance may have other applications available and your default thumbnail will differ from the one below.

Running the app on the iOS Simulator:

Click on your app’s card image, scroll down to the PhoneGap Build tile, and click on Download Source.

Select development, then download and unzip the folder.

Using the  Terminal app  navigate to the root directory of the unzipped folder and run the following command:

phonegap run ios --emulator

Congrats! You now have your first AEM app up and running!

If you would like to run the app locally on your iPhone, the We-Shop.xcodeproj is located in platforms/ios and you can plugin your iPhone and build and run using your device if you have the proper developer licensing from Apple.

Running your app on a mobile device using the PhoneGap Enterprise App:

Using the PhoneGap Enterprise mobile app you can quickly test out any changes that you make to your AEM App on a physical device. This is useful for both development and marketing because any changes can be tested before they are published to your app’s user base.

Step 1) Install PhoneGap Enterprise on your appropriate device:

iOS download

Android download

Step 2) Startup your local AEM 6.1 server by running the .jar file.

Step 3) Navigate to the system console

Step 4) (See Image below) Perform ‘command f’ and search for referrer filter and click on the row

with the title Apache Sling Referrer Filter.

Step 5) Check the box next to Allow Empty and select save.

Step 6) Make sure your mobile device and the host running AEM are connected to the same WIFI, then open the PhoneGap Enterprise app, and select Adobe Experience Manager.

Step 7) Enter the ip of your computer into the PhoneGap Enterprise app followed by a colon and the port of the AEM server, which should be 4502 unless specifically changed:

        eg: 10.4.244.226:4502

Step 8) Enter your user’s credentials  to sign in.

Setting up Brackets for Component Development

Brackets is an open source text editor that has an The AEM Extension to help provide a smooth workflow to edit AEM components and client libraries. The extension will ease the process of synchronizing files between your local file system and the server. This extension also provides some Sightly support, a template language that takes away the complexity of JSP to make component development easier and more secure.

Follow the setup instructions for the AEM apps plugin for brackets and open up the starter kit with brackets.

Select the AEM plugin and open the Project Settings.

If you are running the AEM server locally on your computer enter the following server url and username and passwords as admin. If you are running AEM on a live server enter the url for the aem instance and use the appropriate login information.

Lastly from the file menu select File > Install command line tools, which will allow us to easily open files and folders in brackets.

Creating a reusable component in AEM:

In this tutorial we will be creating a component to display the device information using the App Version Cordova plugin.

In this tutorial you will learn:

To create a new component we will use CRXDE Lite, which is a web-based content repository browser built into AEM. CRXDE Lite gives you a broad set of tools to easily create a project, create and manage files, folders, templates, components, dialogs, nodes, properties, and scripts.

Open up CRXDE Lite to see where our mobile app lives on the server: localhost:4502/crx/de

The structure of a PGE app:

The location of the components and templates that make up our app are located in:

/apps/[company_name]/[app_name]/

In our local copy of the starter-kit this folder is contained in the content-dev module.

The location of our app content that is generated using the components and templates are located in:

/content/phonegap/[company_name]/en

In our local copy of the starterkit this folder is contained in  the content-author module. Any content that you create using the AEM Authoring mode, such as creating a new page, or dragging and dropping a component will be located at this path.

The starter-kit components use JavaServer Pages(.jsp) for templating. JSP is similar to PHP, but it uses the Java programming language. With the introduction of AEM 6.0 Adobe started using Sightly for their templating language and the foundation components for AEM were rewritten using Sightly and can be found in /libs/wcm/foundation/components.

The design of our app is located under:

/etc/designs/phonegap/[company_name]/[app_name]/clientlibsall/css

To add new css styling to your project add it under the ionic-custom.css file.

Notice the css.txt and js.txt inside the clientlibsall folder. To increase the speed of rendering a webpage only the needed components should be loaded from the server, instead of every single file on the webpage.

AEM has a feature called Client Libraries which allows you to store client-side code in the repository, organize it into categories, and define when and how each category of code is to be served to the client. The Client Libraries system then takes care of producing the correct links in your final webpage to load the correct code.

More information on Client Libraries can be found here.

Adding the Cordova app-version plugin to your project:

This plugin will display the version of our app. Take a quick look at how to use the library here

1) In Terminal navigate to the root directory of the aem-phonegap-starter-kit folder and navigate to the phonegap folder:

cd content-dev/src/main/content/jcr_root/content/phonegap/[app_name]/shell/_jcr_content/pge-app/app-content/phonegap

Make sure to replace [app_name]

2)  Use the phonegap CLI to add the plugin:

phonegap plugin add https://github.com/whiteoctober/cordova-plugin-app-version.git

Navigate back to the previous directory:

        cd -

Open up the content-dev folder in Brackets by entering the following command in terminal:

        brackets content-dev

Lastly we need to upload the new phonegap files, so from the file menu select AEM > Export Content Package

Creating a Component

We will start by creating the files that we require using CRXDE Lite and then check them out to our local file system to edit and finally commit our changes to create a working component.

In the application generated using the starterkit, a component group is defined for the applications components. Any component in this group, as well as all of the components in the Phonegap and Phonegap API groups can be used in our application. Other components can be allowed by changing the design settings. But for simplicity, we will create a new component in the generated group. To get the name of this generated group, open CRXDE Lite and navigate to the ionic-menu-list component:

        /apps/[company_name]/[app_name]/components/ionic-menu-list

With ionic-menu-list selected, copy the value of componentGroup, then click on the components folder (so the new component will be created in this directory) and from the file menu select Create Component.

Fill out the form as follows and replace Group: with the componentGroup that you copied.

Hit next, leaving the Advanced component settings blank, and continue through allowed parents and allowed children and select OK.

You should now see a node with the label phonegap-device and a phonegap-device.jsp(if you change the name of the component make sure the .jsp file matches)

In order for a component to appear in the Author mode of AEM, it needs to have either a dialog or a cq:EditConfig node. In this case, our component isn’t editable by an author, so there’s no need for a dialog and we will simply add a node named cq:EditConfig.

Select the phonegap-device node and from the file menu select Create…> Create Node. In the dialog box enter cq:EditConfig for both the name and type.

Adding properties and childnodes to the cq:EditConfig node will change the edit behavior for the component in authoring mode in AEM, such as drag and drop functionality for assets that are available for an image component. Further documentation on configuring the edit behavior of a component can be found here.

Next we need to create a Client Library folder to store the JavaScript that will control our component.

With phonegap-device selected, choose Create Node from the file menu and fill out the form as follows:

        Name: clientlibs

        Type: cq:ClientLibraryFolder

Next select the clientlibs folder that we just created and create two files within the clientlibs folder:

        js.txt

        phonegap-device.js

Before we copy the new files to our local file system the js.txt only requires a small change.

Open js.txt by double-clicking the node and add the following line of code so the clientlibs folder can determine what files to include:

phonegap-device.js

Select Save All in CRXDE Lite

Next we will copy our changes to our local file system:

Open the content-dev folder with brackets and from the file menu select Import Content Package to download the new files.

In the side panel of Brackets navigate to the phonegap-device.js file located under:

src/main/content/jcr_root/apps/[company_name]/[app_name]/components/phonegap-version/clientlibs

Enter the following code and save.

;(function (angular, window, undefined) {

    "use strict";

    angular.module('phonegapVersion', ['btford.phonegap.ready'])

        .controller('VersionCtrl', ['$scope', 'phonegapReady',

            function ($scope, phonegapReady) {

            $scope.version = undefined;

            var determineVersion = phonegapReady(function() {

                if (window.cordova && window.cordova.getAppVersion) {

                    window.cordova.getAppVersion(function(version) {

                       $scope.version = version;

                    });

                }

            });

            determineVersion();

        ]);

}(angular, window));

*Note If you are new to angular.js take a look at the developer guide.

Here we are creating a module called phonegapVersion and importing the btford.phonegap.ready library. The btford.phonegap.ready provides us with a function called phonegapReady that is called after our phonegap app is initialized. Next we are giving our controller the name VersionCtrl. The getAppVersion function is provided by the cordova library and here we are attaching the version variable to $scope.

Next open up phonegap-device.jsp:

You should see the following line, however we won’t need any java code, so add the html after the %> closing jsp tag.

<%

        // TODO add you code here

%>

<div class="row" ng-controller="VersionCtrl" ng-cloak>

    <div class="col col-33 col-offset-67">

        <p class="calm">${'Version:' @ i18n} {{version}}</p>

    </div>

</div>

Here we are creating a top level ng-controller and attaching the VersionCtrl that we defined in our js file. Inside the {{}} we are accessing the version variable that we bound to $scope.

Lastly we need to add our new angular component to the list of modules to import.

Navigate to the ng-ionic-page component and open the angular-module-list.js.jsp, which is located under:

/content-dev/src/main/content/jcr_root/apps/[company_name]/[app_name]/components/ng-ionic-page

%>[

'ngRoute',

'ngTouch',

'ngAnimate',

'ngSanitize',

'cqContentSync',

'cqAppControllers',

'cqAppNavigation',

'snap',

'ionic',

'phonegapVersion'

]

From the menu bar in Brackets select AEM and export the content package to push the changes to the server.

Now that our component is successfully implemented lets create a new Settings page to display our component.

Step 1 ) Open your app from the Admin Console:

Step 2) On the managed content tile click English.

Step 3) Select the + Create and Create Page

 

Step 4) Fill out the following information for the Settings Page, then select Done and Open Page.

Step 5) You should see a new card Settings card. Hover over the card with your mouse and select the pencil icon to modify the page.

Next select edit from the top navigation menu, and then select the side panel.

Click on the Components tab

You should see Device in the list of components. Drag and drop it onto the app and then select preview from the navigation tab.

Congrats you now know how to create a reusable component! The component should not display any information because it needs to be run on a mobile device. You can run it in the PhoneGap Enterprise app, but there is currently no way to navigate to the Settings page that we just created. Follow along the next tutorial to learn how to add a navigational component into the hamburger menu located at the top left of the app.

Intro to Templates: Adding a navigation item to the Hamburger Menu

In this tutorial you will learn how page navigation is implemented in PGE apps. We will be adding a new Settings item to the hamburger menu list that will navigate to the Settings page that we created in the previous tutorial.

The hamburger menu is a part of every new page that we have created, so we will need to modify the component associated with this template. We will start off by exploring the properties of the template, followed by the page component and lastly we will modify the hamburger menu that is inside the page component.

Open up CRXDE to

 /apps/[company_name]/[app_name]/templates/ng-ionic-page

This ng-ionic-page is the template that shows up in the AEM Admin console when you select ‘Create New Page’.

Select ng-ionic-page node and you should see in the properties panel the title and description that show up in the prompt when you create a new page. AllowedPaths controls the scope of the template, so it can be configured to be available for any PGE app, or only the app that it is defined in.

Expand the ng-ionic-page node:

The thumbnail.png is the image that appears when you create a new page and can be customized.

Click on the jcr:content node

Looking at the properties panel we can see that the css styling used for the design of the template is located under

/etc/designs/phonegap/[company_name]/[app_name]

Under sling:resourceType we can see the ng-ionic-page template is created using the ng-ionic-page component. (in the sling:resourceType, /apps is removed from the path, so the location of the component on CRXDE Lite should be /apps/[company_name]/[app_name]/components/ng-ionic-page). This is the component that we will need to modify to add another item to the hamburger menu.

Navigate to /apps/[company_name]/[app_name]/components/ng-ionic-page

Open up the menu.jsp and add the following code:

You will need to change the path in the go function, which is described below.

<%@page session="false"

            import="com.day.cq.wcm.api.WCMMode,

                    com.adobe.cq.mobile.angular.data.util.FrameworkContentExporterUtils" %><%

%><%@include file="/libs/foundation/global.jsp" %><%

%>

<div class="list">

    <a class="item item-button-right" ng-click="updateApp()">

        Update

        <button class="button button-positive">

            <i class="icon ion-ios-cloud-download-outline"></i>

        </button>

    </a>

    <a class="item item-button-right" ng-click="go('/content/phonegap/We-Shop/en/settings', 'Settings')">

        Settings

        <button class="button button-positive">

            <i class="icon ion-ios-gear-outline"></i>

        </button>

    </a>

</div>

Here we are creating link item inside the menu list.  Ionic provides us with a set of classes to style the content. Item-button-right sets the styling for the html button and moves it to the right. This is the same blue bounding box that surrounds the update icon. Inside the button notice the ion-ios-gear-outline. Ionic has a list of free icons that you can use in your css styling so you can easily change the look of the icons.

Notice the ng-click function. This functionality is defined by angular.js and when a user presses on the icon, ng-click is triggered and calls the go function. Normally page navigation is handled by angular, but we will be using the go function provided in PGE, which is defined in app-navigation.js and located at:

/apps/[company_name]/[app_name]/components/ng-ionic-page/clientlibs/app-navigation.js

The go function takes the path of a page as its first parameter and for the second parameter a legible value that is passed to the Analytics, as opposed to a long path. You will need to change the path of the settings page to match the name of your app:

 go('/content/phonegap/[app_name]/en/settings', 'Settings')

Save the file and preview one of the pages from the Author Mode. Make sure you are in Preview mode and click on the hamburger menu. You should see a new Settings item. Try clicking on  Settings and make sure that it navigates to the appropriate page. If you are taken to a page with ‘No resource found’ make sure the capitalization of settings is correct in the path.

 

Creating a Tab Bar for Navigation

In this tutorial you will learn how to create a tab bar with multiple icons that will navigate to a new page when pressed.

To add in a tab bar we will need to modify the ng-ionic-page component so that every page that is created will have the tab bar attached. In the next tutorial we will pull out the tab bar into a separate template.

In CRXDE Lite navigate to /apps/[company_name]/[app_name]/components/ng-ionic-page

Open the body.jsp and scroll down to the bottom.

Notice the <cq:include script="footer.jsp"/>. This file is defined in the SuperType of ng-ionic-page, which you can locate by clicking on the ng-ionic-page node and looking under sling:resourceSuperType. We want the tab bar to be the last content rendered, so we will override the footer.jsp file. Creating our own version of the footer.jsp file will override the one defined in the SuperType of ng-ionic-page, but fortunately it is left empty, so we will not be overriding any important functionality.

Step 1) Click on the ng-ionic-page node and select Create File and name it: footer.jsp

Step 2) Using the ion-tabs directive provided by ionic create three ion-tabs. Paste the following code in the footer.jsp file.

<%@page session="false"

            import="com.day.cq.wcm.api.WCMMode,

                    com.adobe.cq.mobile.angular.data.util.FrameworkContentExporterUtils" %><%

%><%@include file="/libs/foundation/global.jsp" %><%

%>

<ion-tabs class="tabs-positive tabs-icon-only">

  <ion-tab title="Home" icon-on="ion-ios-home" icon-off="ion-ios-home-outline" ng-click="go('/content/phonegap/We-Shop/en/home', 'Home')">

  </ion-tab>

  <ion-tab title="Nearby" icon-on="ion-ios-location" icon-off="ion-ios-location-outline" ng-click="go('/content/phonegap/We-Shop/en/nearby', 'Nearby')">

  </ion-tab>

  <ion-tab title="Scanner" icon-on="ion-ios-barcode" icon-off="ion-ios-barcode-outline" ng-click="go('/content/phonegap/We-Shop/en/scanner', 'Scanner')">

  </ion-tab>

</ion-tabs>

Notice that we are using three new pages called home, nearby and scanner. These pages have not been created yet, so go ahead and navigate to the apps dashboard and click on the app, then in the English tile under Managed Content create three new pages with the corresponding titles. If you leave the Name section blank it will default to a lowercase version of the title.

After you have created the three new pages make sure you modify the path in the go function:

go('/content/phonegap/[app_name]/en/home', 'Home')

Hover over the edit icon on one of your newly created pages and you should see the tab bar. Try clicking on each tab and make sure that it navigates correctly. If you are taken to a page with ‘No resource found’ make sure the capitalization of the pages in the go function are correct. In the next tutorial we will cover how to create a new template page by turning the tab bar into a separate template.

Creating a Template Page:

This is dependant on the previous tutorial Creating a Tab Bar for Navigation, so please complete it first before proceeding.

Not every page in our app will need to have a tabbar, so it would be helpful to turn the tabbar page into a custom template so that a marketer could create a new page with or without the tab bar.

In CRXDE Lite navigate to the components section of your app and create a new component. While selected on the components folder create a new component with the following information, but replace the Super Type field with the path to the ng-ionic-page component located at:

apps/[company_name]/[app_name]/components/ng-ionic-page

Notice that for Super Type /apps is removed from the path.

Click Next and continue through the following pages leaving them blank, then select OK.

Setting the Super Type to ng-ionic-page allows our component to inherit all the files and properties associated with the ng-ionic-page. This means the only modification needed is to add the footer.jsp file that we created in the previous tutorial.

Expand the ionic-product component and drag and drop the footer.jsp from ng-ionic-page under the ng-ionic-tabbar-page node. The purpose of this is to make sure the original ng-ionic-page has its original functionality, while our new component has the tab bar.

Lastly right click on the ng-ionic-tabbar-page.jsp and delete the file. Your final node structure should look like the following:

Now that we have a component we need to create a template to display when the user creates a new page from the AEM dashboard.

Step 1) Expand the templates folder, right click on the ng-ionic-page and select copy.

Step 2) Right click on the templates folder and select paste.

Step 3) Right click on the new template, select Rename and call it ng-ionic-tabbar-page.

Step 4) Select ng-ionic-tabbar-page node and modify the properties panel.

  1. double click value column of jcr:title and rename the template to Ionic Tab Bar PhoneGap page
  2. change the jcr:description to: Template for building Ionic PhoneGap pages with a tab bar

Step 5) Select the jcr:content node located directly under the ng-ionic-tabbar-page node.

  1. Set the sling:resourceType to the location of the ng-ionic-tabbar-page component. In our case it is Adobe/We-Shop/components/ng-ionic-tabbar-page, but replace Adobe and We-Shop with your appropriate company and app name.

Select Save All, then open up the AEM app dashboard and under the English content select Create Page.

 

You should see our brand new template page as one of the options. Select the Ionic Tab Bar Phonegap Page and give it any name and description that you would like.

Congrats you now know how to create a new template page!

*Note home, nearby and scanner pages that we created in the previous tutorial will not have a tabbar any more, so we could delete the pages and recreate them as Ionic Tab Bar Phonegap Pages, but it will be easier to modify the resource type and template for the pages through CRXDE Lite.

The content that we generate through the AEM Apps console is located in CRXDE Lite under  

/content/phonegap/[app_name]/en

Navigate to the en content, expand the home page and click on the jcr:content:

In the properties panel modify the value of sling:resourceType and cq:template to be a ng-ionic-tabbar-page.

Repeat the same process on the nearby and scanner page.

Select Save All and preview one of the three pages and the tab bar should appear at the bottom of the page.

Customizing the navigation header and tab bar:

In this tutorial you will learn how to quickly change the color of the navigation header and tab bar.

In CRXDE Lite open up template.jsp for the ng-ionic-page located at:        

/apps/[company_name]/[app_name]/components/ng-ionic-page/template.jsp

The header bar is defined as a div with a bar-positive style. This is an ionic style and for this app we will use stable.

<div class="bar bar-header bar-stable">

A list of the different styles is available here

Next open the footer.jsp file in the ng-ionic-tabbar-page component located at:

        /apps/[company_name]/[app_name]/components/ng-ionic-tabbar-page/footer.jsp

Modify the ion-tabs class to ion-stable.

<ion-tabs class="tabs-stable tabs-icon-only">

Documentation on customizing the ionic tabs is available here. Also note that you can create a tabbar with titles underneath, or to the side of the icons.

Creating a Reusable Grid Layout Component:

In this tutorial we will be creating a component that will generate a grid of columns and rows to place other PGE components into.

This example contains 1 image component at the top with the Featured image and below it is the grid layout component that we will be developing. The grid layout component will be customizable to have a variable number of rows and columns. Currently in the example it is set to 2 columns and 3 rows and an image component has been placed in each cell.

The image assets are available to download here.

Creating the Component

Navigate to CRXDE Lite and select the components folder located under /apps/[company_name]/[app_name]/components.

Create a new component called ionic-grid-layout and set its sling:resourceSuperType to foundation/components/parbase. Parbase is a base component which should be extended for any component intended to be used inside the AEM paragraph system (parsys)..

Open the ionic-grid-layout.jsp and enter the following code:

<%@ page session="false" %><%

%><%@include file="/libs/foundation/global.jsp"%><%

int rows = properties.get("num-rows", 1);

int col = properties.get("num-columns", 2);

int imageCount = 0;

for (int i = 0; i < rows; i++) {

    %>

    <div class="row">

       <%

        for (int j = 0; j < col; j++) {

            imageCount++;

            String includePath = "content-par" + imageCount;

            %>

            <div class="col">

            <cq:include path=includePath resourceType="foundation/components/parsys" />

            </div>

            <%

       }

            %>

    </div>

    <%

}

%>

First we are getting the number of rows and columns from the dialog box, then for every row we generate a div with a class of row and we create the columns.

Inside the column div we call cq:include path. This is where we generate a parsys file, which is the file type of a customizable cell.

Notice the properties.get method. This is used to retrieve the properties from a dialog box, so our next step is to create a dialog box with two properties, num-rows and num-columns.

Click on the ionic-grid-layout node and select create dialog with the following content:

        Label: dialog

        Title: Grid Layout

Double click on the new dialog to open a preview.

The Tab 1 is auto generated and we only need one tab, so lets remove it and then add the dialogs for column and rows.

Step 1) Expand the dialog node, as well as the items node and delete the nested items node.

Step 2) Select the items node and in the properties panel right click on xtype and select delete.

Step 3) While still selected on the items node create a new node with the following properties:

        Name: num-rows

        Type: nt:unstructured

Step 4) Select the num-rows node and add the following properties:

Documentation on the property types for a dialog is available here.

Step 5) Copy the num-rows node, then select the items node and paste.

Step 6) Rename the new node to num-columns and change the following properties:

        defaultValue: 2

        fieldLabel: Number of Columns

        name: ./num-columns

Our ionic-grid component is complete, so to test it out open up the home page in the Author Mode.

First drag and drop an Image component onto the page for the Featured page, then drag and drop the new Grid component below.

Click on the bounding box that contains the ‘drag components here’ elements and select the settings icon:

Input two columns and 3 rows into the dialog and then drag an image component into all 6 cells.

Lastly edit the Image components and upload the corresponding images from the AEM assets folder that available for download at the beginning of this tutorial. In the next tutorial we will create a product component and link the images to the various product pages.

Adding 3rd Party Javascript Libraries to your AEM App

There is no need to reinvent the wheel when developing mobile apps, so in most cases you will need to add a third party javascript library into your AEM app. The component that we are developing in the next section is dependant on the ionic.js library and the ionic-angular.js library, so we will be adding these into our project. *Note the most recent version of the StartKit includes ionic.js, so you will just need to include ionic-angular.min.js to your project. Previously we have clientlib folders inside our components, however the scope of the clientlib folder is limited to the component. To make our javascript library available across the app make the following changes:

Step 1) Start by downloading the following two files:

http://code.ionicframework.com/1.1.0/js/ionic.min.js

http://code.ionicframework.com/1.1.0/js/ionic-angular.min.js

Step 2) Open up CRXDE Lite and navigate to etc/clientlibs/[company_name]/ionic-1.0.0-beta.13

Step 3) While selected on the ionic folder create a new file called js.txt and create a folder called js.

Step 4) Create two files inside the js folder called ionic.min.js and ionic-angular.min.js

Step 5) Copy and paste the code from the corresponding ionic files downloaded from step 1

Step 6) Add the the two files to the js.txt so they will be imported as a clientlib and Select Save All:

#base=js

ionic.min.js

ionic-angular.min.js

*Note etc/clientlibs/ is a folder and not a ‘clientlib’, so we need to create a node that will bundle the javascript that we added to the ionic folder and make it globally available to the app.

Step 7) Navigate to content/phonegap/[app_name]/shell/app-config and copy and paste the angular.js node into the same location. This node has all the same properties that we need, so it is faster to just change the name and path to the js client library.

Step 8) Rename the copy of angular.js to ionic.js and in the properties panel change the targetRootDirectory to /etc/clientlibs/[company_name]/ionic-1.0.0-beta.13

Step 9) Copy the ionic.js node and paste it under the app-config-dev node located just below app-config

Step 10) We need to import our new clientlib folder and make it accessible to every page, so navigate to the ng-ionic-page component and add the following line to js_clientlibs.jsp file:

<cq:includeClientLib js="Adobe.ionic-1.0.0-beta.13"/>

Now we can use the ionic.js library in any ng-ionic-page, including the ng-ionic-tabbar-page. This will allow us to create a product component in the next tutorial that allows a user to swipe through multiple images of the product.

Creating a Product Card

In this tutorial we will be creating a drag and drop product component that will use a dialog to pick the number of images to display, as well as the title of the product, the price and description.

Step 1) Open CRXDE Lite and navigate to apps/[company_name]/[app_name]/components

Step 2) Click Create > Create Component and give it the name ion-product

Step 3) Create a clientlibs folder and within the folder create 2 files,  ionic-product.js and js.txt

Step 4) Open the js.txt and add the following line and save the file:

ionic-product.js

Step 5) Copy the dialog component that we created in the ionic-grid tutorial and paste it under the ionic-product node.

Step 6) Copy and paste num-rows two more times and rename the nodes to the following:

 

Step 7) update the following properties in the item nodes:

        title:

                fieldLabel: Title

name: ./title                

xtype: textfield

        description:

                fieldLabel: Description

name: ./description                

xtype: textfield

        price:

                fieldLabel: Price

name: ./price        

xtype: textfield

        num-images:

                fieldLabel: Number of Images

name: ./num-images

xtype: numberfield

Add the following code to ionic-product.jsp

<%@ page session="false" %><%

%><%@include file="/libs/foundation/global.jsp"%><%

    String title = properties.get("title", "Title");

        String description = properties.get("description", "Description");

        String price = properties.get("price", "Price");

        int imgCount = properties.get("num-images", 1);

%>

<ion-content padding="true" class="has-header" style="position: relative;">

    <div class="list card">

        <div class="item item-body">

            <div ng-controller="SlideController">

                    <ion-slide-box active-slide="myActiveSlide" show-pager="true" does-continue="true">

                    <%

                    for (int i = 0; i < imgCount; i++) {

                        String includePath = "product-image" + i;

                        %>

                        <ion-slide>

                        <cq:include path=includePath resourceType="mobileapps/components/image" />

                        </ion-slide>

                        <%

                    }

                    %>

                    </ion-slide-box>

            </div>

            <h2><%= xssAPI.encodeForHTML(title) %></h2>

            <h4><%= xssAPI.encodeForHTML(description) %></h4>

            <p><%= xssAPI.encodeForHTML(price) %></p>

        </div>

        <div class="item item-divider item-button-right">

            Checkout

            <button class="button button-light button-icon button-small icon ion-ios-cart-outline"></button>

        </div>

    </div>

</ion-content>

Add the following code to ionic-product.js

;(function (angular, window, undefined) {

    angular.module('ionicProduct', ['btford.phonegap.ready', 'ionic'])

        .controller('SlideController', ['$scope', function ($scope) {

                $scope.myActiveSlide = 0;

            }

        ]);

}(angular, window));

Lastly we need to add our new angular component to the list of modules to import.

Navigate to the ng-ionic-page component and open the angular-module-list.js.jsp, which is located under:

/content-dev/src/main/content/jcr_root/apps/[company_name]/[app_name]/components/ng-ionic-page

%>[

'ngRoute',

'ngTouch',

'ngAnimate',

'ngSanitize',

'cqContentSync',

'cqAppControllers',

'cqAppNavigation',

'snap',

'ionic',

'phonegapVersion',

'ionicProduct'

]

Publishing changes to the app using Over the Air Updates (OTA)

After adding the new component to the app, it’s time to publish our changes to the app that is currently running on a mobile device.

Step 1) Navigate to the apps page and open up the app: http://localhost:4502/aem/apps.html/content/phonegap 

Step 2) Click on the tile with your app name located under the Content Release section:

Step 3) Select the English content package.

Step 4) Click on the drop down arrow and select Stage Update.

Step 5) Fill out your update information and select Done.

Step 5) Select the drop down arrow again and select Publish Updates.

Step 6) Open up your mobile app, slide open the hamburger menu and select Update. The new changes will be downloaded and you should see your new device information.

Next Steps:

The Kitchen Sink app developed by Bruce Lefebvre is a great resource to learn how to develop authorable components that utilize the Cordova/PhoneGap API.

Features:

        Contacts: Loads a list of the user’s contacts

        Geolocation: Displays the lat/lng of your current location with an image of the location on

google maps.

        Compass: Renders an interactive compass that updates based off the device’s hardware.

        Camera: Opens the native camera to take a picture/loads picture from camera library.

        Cellular/Network Connection: Displays the network connection.

        Offline Video: Plays offline videos stored locally in the app.

        In-App Browser: Opens an in-app browser to a desired webpage.

        Library: Loads data from a library folder based off a query. Eg: A page with the label of

CSS queries the library-data folder for products with the tag of CSS.

        Device/OS Information: Displays information of the mobile device and OS version.

*Note to use the components developed in kitchen sink in your app after it is installed, you will need to copy the btford library folder into your project on CRXDE Lite located at:

etc/clientlibs/brucelefebvre/btford

into:

        etc/clientlibs/[company_name]

Add the following line to the js_clientlibs.jsp located at(/apps/[company_name]/[app_name]/components/ng-ionic-page/js_clientlibs.jsp):

        <cq:includeClientLib js="Adobe.btford"/>

        (Change Adobe to the [company_name] of your app)

        

                

The Summit Developer Lab app created by Anthony Rumsey is a great resource for learning AEM app development and contains a set of step by step tutorials.

Features:

AEM Introduction

PhoneGap Introduction

App Development

Advanced Component Development

Managing App Content

Reviewing App Content

Adobe Mobile Services Analytics

About:

This developer guide was created by Torin Blankensmith as a part of an internship at Adobe focusing on technical enablement for AEM mobile app development.

Special thanks to: Bruce Lefebvre, Johnson Ho, John Fait, Justin Edelson and Derek Lu for their help in learning AEM App development and contributions to the guide.

Please send any questions, or inquiries to torin.blankensmith@gmail.com.