Page Structure of an AEM Mobile Cordova Application

Exploration of the mapping between an AEM page structure and an Angular UI Router state structure using the Ionic AEM Apps Library for AEM Mobile Cordova development.

In the first post in this series on AEM Mobile we introduced, or more precisely re-introduced, the Ionic AEM Apps Library and its companion Archetype.  With that introduction out of the way we will start digging into the structure of an AEM Mobile Cordova App (see nomenclature section of the first post if that name doesn’t make any sense) as well as the guts of the Ionic AEM Apps Library / Archetype.

Ionic applications are, by their nature, single page applications.  This means that a user transitions through the screens or “States” of the application without requesting a new webpage.  This aspect of Ionic applications raises challenges in the enablement of application authors.  We want to provide authors with a way to author their applications using the capabilities afforded in AEM Sites, a system largely built for authoring web pages.  Conceptually this can be done in two ways (probably more than two ways but we will look at two).  First, one could expose a single authoring interface for the entire application and have authors build up the single page application in a single page.  Second, one could create a mechanism by which a tree of authored pages is stitched together into the states of a single page application.  

We went with the later.

The concept of pages and the patterns and practices for authoring pages are very familiar to content authors and the concept of screens or “States” in a native application closely parallels these concepts.  The Ionic AEM Apps Library treats every page as a State in the Ionic application.  When authoring, each State is authored as a single page in a tree of pages exposing a familiar authoring experience.  To produce a single page application, the Application Root page component provided by the Library exposes mechanisms to dynamically generate the Angular UI Router configuration for the application based on the page tree below the Application Root.  Each page becomes a state and the parent / child relationship between pages translates essentially to a parent / child relationship between states.  

We can see this in action by building up a small tree of demonstrative pages and seeing what is produced when we render the Application Root in Preview mode.  For the purposes of this example, we will create the following page structure:

  • Application Root

    • State 1

    • State 2

      • Substate 2

      • Substate 1

Within the states themselves we will want to author a bit of content, at least a title to identify the state, and links between states.  For both purposes we can use OOB General components.  When authoring links between states you can simply use components like Text or List and create the links, when the links are rendered in app mode they will be transformed into state fragments.  I personally used the List component and authored a link from State 1 to State 2, and from State 2 to State 1, Substate 1, and Substate 2.

At this point we will get the application ready to be run.  Return to the application root and edit the page properties.  Open the Application tab of the properties and select State 1 as the initial state of the application.  Once saved, preview the Application Root.  You should now see State 1 with your authored links.  You will notice that while you can navigate to Substate 1 and Substate 2, what you see does not actually change.  This is, because we have not established an injection point for the content of the sub states.  

The Ionic Ion Nav View directive (http://ionicframework.com/docs/api/directive/ionNavView/) is what is used to indicate where state content should be injected and the Ion Nav View component provided by the Library allows you to place the directive into a state.  This means that your substate content can be injected anywhere in the parent state where you are able to drag the component, offering full flexibility of layout.  For our simple purposes we will add an instance of the Ion Nav View component as another component in State 2.  Now, when we preview our application and navigate between Substate 1 and Substate 2 we can see the content for these substates appropriately inserted.

State 2 After Authoring

How State 2 looks after authoring

To better understand what the Library is doing with your pages when it turns the tree of pages into a tree of states, you can open the module file for the application (http://localhost:4502/content/mobileapps/todo-mobile-app/en/application.angular-app-module.js).  This file contains, among other things, the $stateProvider configuration generated dynamically by the Library based on the tree of pages authored.

$stateProvider
    .state( 'state-1', {
        abstract: false,
        url: '/state-1',
            templateUrl: 'application/state-1.template.html',
            controller: 'LifecycleBroadcastCtrl'
    } )
    .state( 'state-2', {
        abstract: false,
        url: '/state-2',
            templateUrl: 'application/state-2.template.html',
            controller: 'LifecycleBroadcastCtrl'
    } )
    .state( 'state-2.substate-1', {
        abstract: false,
        url: '/substate-1',
            templateUrl: 'application/state-2/substate-1.template.html',
            controller: 'LifecycleBroadcastCtrl'
    } )
    .state( 'state-2.substate-2', {
        abstract: false,
        url: '/substate-2',
            templateUrl: 'application/state-2/substate-2.template.html',
            controller: 'LifecycleBroadcastCtrl'
    } );

Ionic state routing is based on the Angular UI Router. Familiarity with this mechanism is a must for Ionic developers.

You will notice, in addition to the state id and url, which are derived directly from the page tree, there are a few other properties such as abstract which can be controlled from a state’s page properties.  We will look at these more closely in the next post.  For now, it’s worth playing with the creation of a few more states or more complex trees of states to get a feel for how this translates into a single page application.