ADOBE EXPERIENCE MANAGER (AEM) COMPONENTS

Concept Code Component

An Adobe Experience Manager (AEM) example to demonstrate development of a component for adding concept code to a page using a textarea field. Can be used for testing, prototyping and troubleshooting.

Getting Started

We’re using a AEM Project Archetype Maven template to create the project.

For example,

cd src

mvn -B org.apache.maven.plugins:maven-archetype-plugin:3.2.1:generate \
 -D archetypeGroupId=com.adobe.aem \
 -D archetypeArtifactId=aem-project-archetype \
 -D archetypeVersion=43 \
 -D aemVersion=6.5.0 \
 -D appTitle="My Project" \
 -D appId="myproject" \
 -D groupId="com.myproject" \
 -D language=en \
 -D country=us \
 -D singleCountry=n \
 -D frontendModule=general

Component Folder

Copy the existing helloworld component included with the project to jump start development. For example,

cd src/myproject/ui.apps/src/main/content/jcr_root/apps/myproject/components

cp -a helloworld/. conceptcode/

Update the jcr:root properties for the conceptcode component in the conceptcode/.content.xml as follows.

.content.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="Concept Code"
    componentGroup="My Project - Content"/>

Component Dialog

If you copied the helloworld component, you should already have a dialog to start with. Otherwise, create a folder named _cq_dialog in the conceptcode folder.

The dialog will contain a single textarea for the concept code.

Here is the new XML to use for the apps/myproject/components/conceptcode/_cq_dialog/.content.xml

_cq_dialog/.content.xml
<?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"
    xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Properties"
    sling:resourceType="cq/gui/components/authoring/dialog"
    extraClientlibs="[myproject.cmpconfig.dialog]">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
        granite:class="concept-code">
        <items jcr:primaryType="nt:unstructured">
            <column
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                    <code
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
                        fieldLabel="Code"
                        name="./code"/>
                </items>
            </column>
        </items>
    </content>
</jcr:root>

Let’s go over the changes to the dialog XML above.

  1. The obvious change mentioned above was to use a textarea field for the code. This is apparent in the code element where the sling:resourceType attribute is set to granite/ui/components/coral/foundation/form/textarea.

  2. In the jcr:root element, we’re adding a namespace attribute for the granite document, xmlns:granite="http://www.adobe.com/jcr/granite/1.0". This is for the granite:class attribute in change number 4 below.

  3. Also in the jcr:root element, we’re adding an extraClientlibs attribute with the myproject.cmpconfig.dialog category specified. This attribute value contains an array for all of the extra client-libs the dialog depends on. The client-lib and its category will be created further down in this tutorial.

  4. In the content element, we’re adding an attribute to apply a CSS class to the markup that is output for the .coral-FixedColumn container. By doing this we can apply our dialog CSS just for the elements within the container. Steps on where to add the respective CSS further down.

Component Template

Here is the new HTL (Sightly) to use for the apps/myproject/components/conceptcode/conceptcode.html. If you copied the helloworld component, the following replaces all of the pre-existing HTL.

conceptcode.html
<sly data-sly-set.emptyText="${properties.code ? 'Configured' : ''}"/>

${properties.code @ context = 'unsafe'}

<sly data-sly-use.templates="/apps/core/wcm/components/commons/v1/templates.html"
     data-sly-call="${templates.placeholder @ isEmpty = true, emptyTextAppend = emptyText}" />

The emptyText variable is used to provide a placeholder label for the container in editmode so it isn’t collapsed or hidden.

AEM Concept Code component parsys unconfigured

If the properties.code textarea field is not empty, the label will show “Configured”.

AEM Concept Code component parsys configured

Dialog CSS

This is how the dialog and code entry textarea looks prior to our extraClientLibs CSS.

AEM Concept Code Properties Dialog Before CSS Changes

Create a new clientlib-dialog folder that contains a css folder in the project’s clientlibs. For example,

cd src/myproject/ui.apps/src/main/content/jcr_root/apps/myproject/clientlibs

mkdir -p clientlib-dialog/css

Create this dialog.less (Leaner Style Sheets) file in the css folder.

css/dialog.less
.concept-code {
    .coral-Form-fieldwrapper {
        display: flex;
        flex-direction: column;
        height: 100%;
    }
    .coral-FixedColumn-column {
        width: 100%;
        height: 100%;
    }
    .coral-Form-field.coral3-Textfield {
        height: 100%;
    }
}

Create this css.txt file in the clientlib-dialog folder.

css.txt
#base=css
dialog.less
  • #base=css sets the root as the folder named css below the cq:ClientLibraryFolder.
  • dialog.less sets the path of the source files relative to the root folder.

In the clientlib-dialog folder, create a .content.xml to define the client library properties. Note that the jcr:root element contains the categories attribute [myproject.cmpconfig.dialog] for the dialog’s extraClientLibs mapping.

.content.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0"
    xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:ClientLibraryFolder"
    allowProxy="{Boolean}true"
    cssProcessor="[default:none,min:none]"
    categories="[myproject.cmpconfig.dialog]"
    dependencies="[granite.utils]"/>

Adobe Experience League Documentation: Using Client-Side Libraries

With the CSS being applied from the myproject.cmpconfig.dialog category, the textarea fills the width and remaining height of the column container.

AEM Concept Code Properties Dialog After CSS Changes

Example dialog with inline script entered into the code textarea.

AEM Concept Code component dialog with an inline script

After saving the dialog, the page renders with the updated code.

AEM Concept Code component configured with a script

Install

You can use mvn clean install to build and deploy it. e.g.,

mvn -PautoInstallPackage clean install

Source Code

Part 6 of 6 in the AEM Component Dev series.

Part 1 | Multifield Component

comments powered by Disqus