June, 13 2016
Building an AEM Admin interface, also known as a console, is not a trivial task at first glance. This post describes how to create an admin console for AEM 6.2 to
delete centralized data.
Source Code: available here
What are we building?
A method to create content in centralized location that can be shared across many different sites and locales. In our case, we will be creating calendar entries to convey data center uptime for our Pug Ranch's Live Video Feed.
Why are we building this?
Typically components get localized across many locales. This creates live copies of data across our Oak repository. Our data does not need to be localized because our data center uptime covers all locales. By centralizing the data, we remove it from the localization process and remove unnecessary localized nodes.
High Level Design
The design can be broken down into three high-level pieces.
- Admin Console Menu Item
- Admin Console Content, Components, and Clientlibs
- Servlet to handle creating and editing of data
Creating Console Menu Item
Below is the structure of our menu item. It's important to know that we need to overlay the existing
idcorresponds to the
- Icon should be labeled with a corresponding Coral UI icon name.
- Href should point to the location of your console (defined later)
The full uptime menu item JCR node description:
Once you have made the above nodes, you will be able navigate to AEM (1) Tools (2) Operations (3) and Data Center Uptime (4).
Admin Console Content, Components, and Clientlibs
The next piece we need to build is the actual console and the components within the console. This is the most complex piece, so let's break this down further:
- Admin - This is the main view to list our entries. It's defined by a .content.xml
- createEntry - This is the create view. It's is also defined by a .content.xml
- editEntry - This is the edit view. Surprise, also defined by a .content.xml
- Datasource - This is a JSP that provides data (our entries) to our list.
- Uptimeentry - As we iterate through our list of entries, this defines the view for each entry.
- Uptimeform - This handles both create and edit operations.
- Clientlibs - This single JS will provide:
- A Granite Delete Confirmation Dialog
- AJAX Call to delete an entry. It leverages the SlingPostServlet for simplicity.
- Pass a path parameter to our editEntry page.
Content / Admin
This file is huge, so go take a look here. If you've ever worked with
ui.content this file should feel familiar as we're declaring almost all of our layout in XML.
- consoleId should match our Menu Item "id" we created above.
- The clientlibs node allows us to include clientlibs. In our case, Coral 3 and our own uptime clientlib.
- Our list and datasource are what pull in the list of entries. The datasource component will be covered later.
- itemResourceType is used to display each entry. It will also be covered later.
- Within actions, the selection nodes (delete, edit) are used when selecting an item in the list.
- Within actions, the secondary action always shows and is used for create. It's uses a plain href property since no params need to be passed.
Content / createEntry & Content / editEntry
- These files are identical with the exception of one line: the
textproperty of the
contentnode that has a property of
granite/ui/components/coral/foundation/form. This has a property of
actionthat submits to our servlet,
/bin/pugranch/uptimeEntrywhich will be defined later.
- The node
pugranch/admin/ext/uptime/components/uptimeformwhich we will build later using Sightly, Coral, and HTML.
Components / datasource
This component is not a typical front-end style component. We only need the folder and the JSP. You can find the source here.
- The goal of the data source is to find resources, and build an iterable list of those resources.
- It's important to know that for any value you want exposed, you must add that to the ValueMap of the child. You cannot rely on typical resource methods I.E. resource.getPath, resource.getName if you do not include those values in the datasource.
- Working in JSP is not fun, but it's a bit more direct than Sightly + Java.
Components / uptimeentry
This component takes the entries from our data source and uses the values provided to display each entry. Source here.
- Again, it's important to know that the only values we have available to us are coming directly from the datasource. Typical methods you would use to get values from a resource are not available here.
- A lot of the Coral UI classes and naming conventions are using 6.2 conventions. Your mileage may very.
Components / uptimeform
This component is the inside of our createEntry and editEntry form. In the case of editEntry, we have a use class to provide additional logic to pull in information. Source here.
- We're again using some Coral Kung Fu to create our form elements.
- We are using a Sling convention,
:redirectto provide our servlet with the location we want to be redirected to upon successful entry creation.
- Remember, our form
methodwere declared in our content nodes, so the do not need to be declared here.
- The step value (.01) seems to have a bug with rouding, so we fix this in our servlet.
Clientlibs / pugranch.uptime
Functions to Note:
- Register the buttons during a selection change.
- Toggle the Delete Dialog when "Delete" is clicked.
- Handle the Confirm Deletion - Uses an AJAX call and Sling Post Servlet conventions to delete the node.
- Handle the "Edit" action - Passes the path to the editEntry.
The Uptime Entry Servlet Performs the functions listed below. Source code here.
- Create an uptimeCalendar sling:OrderedFolder if needed.
- Create or update an uptime entry. The naming convention is YEAR-Month.
- Redirect to the location based on :redirect.
In the end, you should have something that resembles the screenshot below. It can seem daunting at first, but if you walk through each piece, creating an admin console can be very similar to a lot of core AEM concepts.