This part 1 of a 2 part in series illustrating how to develop for AEM Projects. In this tutorial we will create a custom Project template that can be used to create new Projects within AEM for managing content authoring workflows and tasks.

Introduction

AEM Projects is a feature of AEM designed to make it easier to manage and group all of the workflows and tasks associated with content creation as part of an AEM Sites or Assets implementation.

AEM Projects comes with several OOTB project templates. When creating a new project, authors can choose from these available templates. Large AEM implementations with unique business requriements will want to create custom Project templates, tailored to meet their needs. By creating a custom Project template developers can configure the project dashboard, hook into custom workflows, and create additional business roles for a project. We will take a look at the structure of a Project Template and create a sample one.

custom-project-card

Setup

This tutorial will step through the code necessary to create a custom Project template. You can download and install the attached package to a local environment to follow along with the tutorial. You can also access the full Maven project hosted on GitHub.


This tutorial assumes some basic knowledge of AEM development practices and some familiarity with AEM Maven project setup. All code mentioned is intended to be used as a reference and should only be deployed to a local development AEM instance.

Structure of a project template

Project Templates should be put under source control and should live beneath your application folder under /apps. Ideally they should be placed in a sub-folder with the naming convention of */projects/templates/<my-template>. By placing following this naming convention any new custom templates will automatically become available to authors when creating a project. The configuration of available Project Templates is set at: /content/projects/jcr:content node by the cq:allowedTemplates property. By default this is a regular expression: /(apps|libs)/.*/projects/templates/.*

The root node of a Project Template will have a jcr:primaryType of cq:Template. Beneath the root node of there are 3 nodes: gadgets, roles, and workflows. These nodes are all nt:unstructured. Beneath the root node can also be a thumbnail.png file that gets displayed when selecting the template in the Create Project wizard. 

The full node structure:

/apps/<my-app>
    + projects (nt:folder)
         + templates (nt:folder)
              + <project-template-root> (cq:Template)
                   + gadgets (nt:unstructured)
                   + roles (nt:unstructured)
                   + workflows (nt:unstructured)

Project Template Root

The root node of the project template will be of type cq:Template. On this node you can configure properties jcr:title and jcr:description that will be displayed in the Create Project Wizard. There is also a property called wizard that points to a form that will populate the Properties of the project. The default value of: /libs/cq/core/content/projects/wizard/steps/defaultproject.html should work fine for most cases, as it allows the user to populate the basic Project properties and add group members.

*Note the Create Project Wizard does not use the Sling POST servlet. Instead values are posted to a custom servlet: com.adobe.cq.projects.impl.servlet.ProjectServlet. This should be taken into account when adding custom fields.

An example of a custom wizard can be found for the Translation Project Template: /libs/cq/core/content/projects/wizard/translationproject/defaultproject

 

Gadgets

There are no additional properties on this node but the children of the gadgets node control which Project Tiles populate the Project's dashboard when a new Project is created. The Project Tiles (also known as gadgets or pods) are simple cards that populate the workplace of a Project. A full list of ootb tiles can be found under: /libs/cq/gui/components/projects/admin/pod. Project owners can always add/remove tiles after a project has been created.

Roles

There are 3 default Roles for every project: Observers, Editors, and Owners. By adding child nodes beneath the roles node you can add additional business specific Project Roles for the template. You can then tie these roles to specific workflows associated with the project.

Workflows

One the most enticing reasons for creating a custom Project Template is that it gives you the ability to configure the available workflows for use with the project. These can ootb workflows or custom workflows. Beneath the workflows node there needs to be a models node (also nt:unstructured) and child nodes beneath specify the available workflow models. The property modelId points to the workflow model under /etc/workflow and the property wizard points to the dialog used when starting the workflow. A big advantage of Projects is the ability to add a custom dialog (wizard) to capture business specific metadata at the start of the workflow that can the drive further actions within the workflow.

<projects-template-root> (cq:Template)
    + workflows (nt:unstructured)
         + models (nt:unstructured)
              + <workflow-model> (nt:unstructured)
                   - modelId = points to the workflow model
                   - wizard = dialog used to start the workflow

Creating a project template

Since we will be primarily copying/configuring nodes we will use CRXDE Lite. In your local AEM instance open up CRXDE Lite

  1. Create a Project Templates Folder

    Start by creating a new folder beneath /apps/<your-app-folder> called 'projects'. Create another folder beneath that called 'templates'.

    /apps/aem-guides/projects-tasks/
                        + projects (nt:folder)
                                 + templates (nt:folder)
    
  2. Copy the Simple Project Template

    To make things easier we will start our custom template from the existing Simple Project template.

    1. Copy and paste the node /libs/cq/core/content/projects/templates/default beneath the templates folder created in Step 1.
    /apps/aem-guides/projects-tasks/
                 + templates (nt:folder)
                      + default (cq:Template)
    
  3. Rename the "default" node copied under /apps to "authoring-project"

    You should now have a path like /apps/aem-guides/projects-tasks/projects/templates/authoring-project.

    1. Edit the jcr:title and jcr:description properties of the author-project node to custom title and description values. 
      1. Leave the wizard property pointing to the default Project properties. 
    /apps/aem-guides/projects-tasks/projects/
             + templates (nt:folder)
                  + authoring-project (cq:Template)
                       - jcr:title = "Authoring Project"
                       - jcr:description = "A project to manage approval and publish process for AEM Sites or Assets"
                       - wizard = "/libs/cq/core/content/projects/wizard/steps/defaultproject.html"
    
  4. Add a new Task Pod to the list of gadgets

    For this project template we want to make use of Tasks.

    1. Add a new nt:unstructured node beneath authoring-project/gadgets called tasks
    2. Add String properties to the tasks node for cardWeight = "100", jcr:title="Tasks", and sling:resourceType="cq/gui/components/projects/admin/pod/taskpod". 

    Now the Tasks tile will show up by default when a new project is created. 

    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
             + team (nt:unstructured)
             + asset (nt:unstructured)
             + work (nt:unstructured)
             + experiences (nt:unstructured)
             + projectinfo (nt:unstructured)
             ..
             + tasks (nt:unstructured)
                  - cardWeight = "100"
                  - jcr:title = "Tasks"
                  - sling:resourceType = "cq/gui/components/projects/admin/pod/taskpod"
    
  5. Add an Approver Role

    We will add a custom Approver Role to our project template.

    1. Beneath the project template (authoring-project) node add a new nt:unstructured node labeled roles
    2. Add another nt:unstructured node labeled approvers as a child of the roles node. 
    3. Add String properties jcr:title = "Approvers", roleclass ="owner", roleid="approvers". 
      1. The name of the approvers node, as well as jcr:title and roleid can be any string value (as long as roleid is unique). 
      2. roleclass governs the permissions applied for that role based on the 3 OOTB rolesowner, editor, and observer
      3. In general if the custom role is more of a managerial role then the roleclass can be owner; if it is a more specific authoring role like Photographer or Designer then editor roleclass should suffice. The big difference between owner and editor is that project owners can update the project properties and add new users to the project. 
    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
        + roles (nt:unstructured)
            + approvers (nt:unstructured)
                 - jcr:title = "Approvers"
                 - roleclass = "owner"
                 - roleid = "approver"
    
  6. Update available Workflows

    By copying the Simple Project template you will get 4 OOTB workflows configured. Each node beneath workflows/models points to a specific workflow and a start dialog wizard for that workflow. In Part 2 of this tutorial we will create a custom workflow for this project. For now delete the nodes beneath workflow/models:

    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
        + roles (nt:unstructured)
        + workflows (nt:unstructured)
             + models (nt:unstructured)
                - (remove ootb models)
    
  7. Add a Custom Thumbnail (optional)

    In order to make it easy for content authors to identify the Project Template you can add a custom Thumbnail. The reccomended size would be 319x319 pixels.

    1. In CRXDE Lite create a new file as a sibling of gadgets, roles, and workflows nodes named thumbnail.png
    2. Save and then navigate to the jcr:content node and double click the jcr:data property (avoid clicking 'view'). 
      1. This should prompt you with a edit jcr:data file dialog and you can upload a custom thumbnail. 
    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
        + roles (nt:unstructured)
        + workflows (nt:unstructured)
        + thumbnail.png (nt:file)
    

Finished XML representation of the Project Template:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:description="A project to manage approval and publish process for AEM Sites or Assets"
    jcr:primaryType="cq:Template"
    jcr:title="Authoring Project"
    ranking="{Long}1"
    wizard="/libs/cq/core/content/projects/wizard/steps/defaultproject.html">
    <jcr:content
        jcr:primaryType="nt:unstructured"
        detailsHref="/projects/details.html"/>
    <gadgets jcr:primaryType="nt:unstructured">
        <team
            jcr:primaryType="nt:unstructured"
            jcr:title="Team"
            sling:resourceType="cq/gui/components/projects/admin/pod/teampod"
            cardWeight="60"/>
        <tasks
            jcr:primaryType="nt:unstructured"
            jcr:title="Tasks"
            sling:resourceType="cq/gui/components/projects/admin/pod/taskpod"
            cardWeight="100"/>
        <work
            jcr:primaryType="nt:unstructured"
            jcr:title="Workflows"
            sling:resourceType="cq/gui/components/projects/admin/pod/workpod"
            cardWeight="80"/>
        <experiences
            jcr:primaryType="nt:unstructured"
            jcr:title="Experiences"
            sling:resourceType="cq/gui/components/projects/admin/pod/channelpod"
            cardWeight="90"/>
        <projectinfo
            jcr:primaryType="nt:unstructured"
            jcr:title="Project Info"
            sling:resourceType="cq/gui/components/projects/admin/pod/projectinfopod"
            cardWeight="100"/>
    </gadgets>
    <roles jcr:primaryType="nt:unstructured">
        <approvers
            jcr:primaryType="nt:unstructured"
            jcr:title="Approvers"
            roleclass="owner"
            roleid="approvers"/>
    </roles>
    <workflows
        jcr:primaryType="nt:unstructured"
        tags="[]">
        <models jcr:primaryType="nt:unstructured">
        </models>
    </workflows>
</jcr:root>

Testing the custom project template

Now we can test our Project Template by creating a new Project.

  1. Navigate to the Projects Home and click Create

    You should see the custom template as one of the options for project creation.

    choose-template
  2. Add a user as an Approver

    After selecting the custom template click 'Next' and notice that when populating Project Members you can add them as an Approver role. 

    user-approver
  3. Notice the Task and other Tiles

    Click 'Create' to finish creating the project based off of the custom Template. You will notice on the Project Dashboard that the Tasks Tile and the other tiles configured under gadgets appear automatically. 

    tasks-tile

Supporting materials

Download

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy