Building Components for AEM Mobile Apps

We build out the functional components of our TODO application and take you on a mental walkthrough of things to consider when developing for AEM Mobile.

Across the last two posts in this series we discussed some of the foundational concepts of the Cordova aspect of AEM Mobile, the Ionic AEM Apps Library, and application authoring in AEM. Now it’s time to actually start building our TODO App.

When authoring and developing components and templates for Ionic applications there is a fundamental difference between the authoring context and the application context which does not exist when authoring and developing for Sites. In Sites, each page you author generally ends up as a page on the site and the authoring occurs largely in a context mirroring the eventual production context. Authoring states of applications is somewhat divorced from the eventual production context, a single page application. Further, from a development perspective, the components and template used for a state will not exist in a vacuum in the eventual application, they will become part of a single page application.

To illustrate this let’s dive right into the development of a TODO Application. You can find the completed application on Github https://github.com/OlsonDigital/ionic-aem-mobile-todo-app. The requirements for our application will be quite straightforward and can be summarized as follows:

  • Users should be able to create new TODO Lists
  • Users should be able to view a List of all of their TODO Lists
    • Each list should present the list’s name, the number of items in the list, and the number of completed items
  • Users should be able to view the items in their TODO List
    • Each item should present the item’s name and the items completion status
  • Users should be able to add TODO Items to a TODO List
  • Users should be able to mark TODO Items as completed
  • Users should be able to delete TODO Items
  • TODO Lists, TODO Items, and the state of TODO Items should persist across user sessions (ie, if a user restarts the app their lists and such should still exist)

The flow of the application states and user experience will be as follows:

  • Upon starting the application, users will land on a TODO Lists state where they will be presented with a list of their lists
  • A user can add a new TODO List by interacting with an Add List button
  • Tapping the Add List button should bring up a New List interface where a user can enter the name of the List they are adding. Once submitted the user should be taken back to the TODO Lists state
  • Tapping a TODO List will take the user to the TODO List screen for that particular list
  • The TODO List screen should present all items in the List with a checkbox next to each
  • Tapping on an item will toggle its completion status
  • Swiping right on an item will remove it from the list
  • New Items can be added to the list by interacting with an Add Item button
  • Tapping the Add Item button should bring up an Add Item interface where the user can enter the name of the Item they are adding. Once submitted the user should be taken back to the TODO List state
Application Flow

Resultant Application Flow

It is important to consider, when thinking through the application flow, that the flow of an application created using AEM Mobile should be authorable, otherwise you are not expressing the full capabilities of the platform. An Application Author should be able to decide tomorrow that they want an about screen to be the first screen of the application and they should be able to make that change and propagate it to the live application without developer intervention. This mindset will direct many of the decisions made in development.

Considering the Development Outside AEM

Prior to considering how such an application would be built using the Cordova aspect of AEM Mobile it is worth considering how we might build it if we were just building a straight up Ionic application outside of AEM.

Given the requirements I would envision the application having two states, a Lists state and a List state. These would both be configured as children of a main menu state so that a shared header can be used and we can use the Ionic back button to go back to the Lists state from the List state. Information about which list is being viewed when the user is on the List state would be transmitted via a slug in the URL for the List state.

Similar to the state count there are two main pieces of functionality, creating and presenting Lists, and creating and presenting Items. The controllers for each of our states would expose the functionality to the states and I would back both controllers by a single TODO List Service. The service would expose methods for creating lists, adding items to lists, requesting lists, and requesting individual lists. The service would also internally handle the persistence to Local Storage.

Page Components and Templates for Application States

With this in mind we can break the functionality into composable AEM Components and Templates which will be authored into an application. First we will focus on the Templates / Page Components. We get three Templates / Page Components “for free” by starting with the Ionic AEM Apps Archetype: Application, Content Sync, and Application State. The first two should never be created by application authors, they are part of the initial content for an application. The third can be used freely by application authors to build up an application. As noted in the prior post, each Application State maps essentially to a UI Router State. So, in order to produce a situation where a parent state is controlling the main header and back button functionality of an application while child states hold the application functionality we look to produce an equivalent content tree.

In order to control application form and to bake in a page header and back button we will create a new Main State Page Component and associated Template. This Page Component can extend the ionic-aem-apps/components/page/application-state resource type and we will override the template.html to present an ion-nav-bar and ion-nav-back-button. To assist application authors we will restrict the usage of the associated Template such that its instantiation is only allowed as a direct child of the Application template. When authored this main state will usually be marked as abstract and authors will just drop an Ion Nav View component into the page’s paragraph system, but we do not technically necessitate that in our implementation.

Building out the Content Tree

With our templates and page components in place we can build out the content tree. We know we are going to need at least two states, a TODO Lists state and a TODO List state, and we know that both are going to be injected into a Main state. The only restriction this imposes on our authored pages is that they must be authored such that the parent state of the TODO Lists state and the TODO List state is the Main state. This does not however imply that the Main page must be the immediate parent of both the TODO Lists and TODO List states, each state’s page properties expose a control allowing you to chose which parent state you want to use allowing for great flexibility in page tree structure.

In order to produce semantically meaningful paths I chose to:

  • Create a main state page using our Main State Page template
    • This state was marked as abstract in the page properties as it will never be visited directly in the application
  • Create a "Your Lists" state page named "lists" as a direct child of the main state page
  • Create a "Lists" state page named "listId" as a direct child of the "Your Lists" page
    • This state's parent was set to the main state in the page properties
    • This state was market as a slug state in the page properties. This means that a property named "listId" (the page's name) will be available via $stateParams in the controller for the state and any children in the $scope hierarchy

For the sake of example I have provided a zip package containing this content structure which can be deployed via the Package Manager.

Functional Component Design

Our attention can now turn to the functional components of the application, the presentation and management of todo lists and todo list items. I have broken this task into two components, one for displaying and managing todo lists and one for displaying and managing the items in a list. The components themselves are quite simple and both interact with a central todoListService which persists lists and their items in localStorage. A more noteworthy feature of these components is the care taken to ensure something representing an end state renders in author mode. While it would be unreasonable to make the components functional outside the context of the fully rendered application, they can be made to look functional, or, in the case of the ToDo App, representative of the final product. In many cases this means significant additional development effort as concerns the front end presentation and specifically the generated HTML. This additional effort is clearly illustrated by both the Todo Lists and Todo List components of our application.

As with our Hello World application, after authoring, we are now free to preview the application in the browser by going to the application root page and switching to preview mode. Presuming nothing has gone awry this will result in a fully functional ToDo List Application running in the browser mirroring with reasonable similarity the user experience of the eventual native application.

Wrapping Up

On more than one occasion I have been asked "would it not be simpler to create a standalone Ionic application and not use AEM Mobile"? The answer is, of course it would be. It would be considerably simpler to create a standalone Ionic application. AEM Mobile layers considerable complexity onto the complexities already introduced by Cordova development. However, the payoff is, when done right, the movement of responsibility for changing the application and potentially the creation of new applications from the developers to the authors, marketers, and product owners.

This essentially concludes our look at the Cordova aspects of AEM Mobile, though one or two accompanying videos will be posted to the Pat & Paul series in the near future highlighting some of the topics discussed and speaking a bit to the Content Sync mechanisms. In the next post in this series we will turn our focus to those aspects of AEM Mobile previously known as DPS, how applications are structured in that ecosystem currently, and how to structure your content and configuration for reuse across these and other facets of AEM.

Links

AEM Mobile Series Part 1: http://www.digitalatolson.com/blog/technology/getting-started-in-aem-mobile-with-the-ionic-aem-apps-library

AEM Mobile Series Part 2: http://www.digitalatolson.com/blog/technology/page-structure-of-an-aem-mobile-cordova-application

Ionic AEM Apps Library: https://github.com/OlsonDigital/ionic-aem-apps

Ionic AEM Apps Archetype: https://github.com/OlsonDigital/aem-apps-ionic-maven-archetype

TODO App: https://github.com/OlsonDigital/ionic-aem-mobile-todo-app

Example Content: https://github.com/OlsonDigital/ionic-aem-mobile-todo-app/tree/documentation/content

Pat & Paul on YouTube: https://www.youtube.com/playlist?list=PLlGWqv32msPdrEofFFzuHzQa9gKphoU_d