Show Menu
TOPICS×

Component Basics

In this chapter we will explore the underlying technology of an Adobe Experience Manager (AEM) Sites Component through a simple HelloWorld example. Small modifications will be made to an existing component, covering topics of authoring, HTL, Sling Models, Client-side libraries.

Prerequisites

Review the required tooling and instructions for setting up a local development environment .

Objective

  1. Learn the role of HTL templates and Sling Models to dynamically render HTML.
  2. Understand how Dialogs are used to facilitate authoring of content.
  3. Learn the very basics of Client-side libraries to include CSS and JavaScript to support a component.

What you will build

In this chapter you will perform several modifications to a very simple HelloWorld component. In the process of making updates to the HelloWorld component you will learn about the key areas of AEM component development.

Chapter Starter Project

This chapter builds upon a generic project generated by the AEM Project Archetype . Watch the below video and review the prerequisites to get started!

Open a new command line terminal and perform the following actions.
  1. In an empty directory, clone the aem-guides-wknd repository:
    $ git clone git@github.com:adobe/aem-guides-wknd.git
    Cloning into 'aem-guides-wknd'...
    
    
    Optionally, you can download the component-basics/start branch directly.
  2. Navigate into the aem-guides-wknd directory:
    $ cd aem-guides-wknd
    
    
  3. Switch to the component-basics/start branch:
    $ git checkout component-basics/start
    Branch component-basics/start set up to track remote branch component-basics/start from origin.
    Switched to a new branch 'component-basics/start'
    
    
  4. Build and deploy the project to a local instance of AEM with the following command:
    $ mvn -PautoInstallSinglePackage clean install
    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] Reactor Summary for aem-guides-wknd 0.0.1-SNAPSHOT:
    [INFO]
    [INFO] aem-guides-wknd .................................... SUCCESS [  0.394 s]
    [INFO] WKND Sites Project - Core .......................... SUCCESS [  7.299 s]
    [INFO] WKND Sites Project - UI Frontend ................... SUCCESS [ 31.938 s]
    [INFO] WKND Sites Project - Repository Structure Package .. SUCCESS [  0.736 s]
    [INFO] WKND Sites Project - UI apps ....................... SUCCESS [  4.025 s]
    [INFO] WKND Sites Project - UI content .................... SUCCESS [  1.447 s]
    [INFO] WKND Sites Project - All ........................... SUCCESS [  0.881 s]
    [INFO] WKND Sites Project - Integration Tests Bundles ..... SUCCESS [  1.052 s]
    [INFO] WKND Sites Project - Integration Tests Launcher .... SUCCESS [  1.239 s]
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    
    
  5. Import the project into your preferred IDE by following the instructions to set up a local development environment .

Component Authoring

Components can be thought of as small modular building blocks of a web page. In order to re-use components, the components must be configurable. This is accomplished via the author dialog. Next we will author a simple component and inspect how values from the dialog are persisted in AEM.

Below are the high level steps performed in the above video.
  1. Create a new page named Component Basics beneath WKND Site > US > en .
  2. Add the Hello World Component to the newly created page.
  3. Open the dialog for the component and enter some text. Save the changes to see the message displayed on the page.
  4. Switch in to developer mode and view the Content Path in CRXDE-Lite and inspect the properties of the component instance.
  5. Use CRXDE-Lite to view the cq:dialog and helloworld.html script located at /apps/wknd/components/content/helloworld .

HTML Template Language (HTL)

HTML Template Language or HTL is a light-weight, server-side templating language used by AEM components to render content.
Next we will update the HelloWorld HTL script to display an additional greeting before the text message.

Below are the high level steps performed in the above video.
  1. Switch to the Eclipse IDE and open the project to the ui.apps module.
  2. Open the .content.xml file that defines the dialog for the HelloWorld component at:
    <code>/aem-guides-wknd/ui.apps/src/main/content/jcr_root/apps/wknd/components/content/helloworld/_cq_dialog/.content.xml
    
    
  3. Update the dialog to add an additional textfield named Greeting with a name of ./greeting :
    <?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:primaryType="nt:unstructured"
        jcr:title="Properties"
        sling:resourceType="cq/gui/components/authoring/dialog">
        <content
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
            <items jcr:primaryType="nt:unstructured">
                <column
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/container">
                    <items jcr:primaryType="nt:unstructured">
                        <greeting
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                            fieldLabel="Greeting"
                            name="./greeting"/>
                        <text
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                            fieldLabel="Text"
                            name="./text"/>
                    </items>
                </column>
            </items>
        </content>
    </jcr:root>
    
    
  4. Open the file helloworld.html , which represents the main HTL script responsible for rendering the HelloWorld component, located at:
        <code>/aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/components/content/helloworld/helloworld.html
    
    
  5. Update helloworld.html to render the value of the Greeting textfield as part of an H1 tag:
    <h1 data-sly-test="${properties.text && properties.greeting}">${properties.greeting} ${properties.text}</h1>
    <pre data-sly-use.hello="com.adobe.aem.guides.wknd.core.models.HelloWorldModel">
    HelloWorldModel says:
    ${hello.message}
    </pre>
    
    
  6. Deploy the changes to a local instance of AEM using the Eclipse Developer plugin or using your Maven skills.

Sling Models

Sling Models are annotation driven Java "POJO's" (Plain Old Java Objects) that facilitate the mapping of data from the JCR to Java variables, and provide a number of other niceties when developing in the context of AEM.
Next, we will make some updates to the HelloWorldModel Sling Model in order to apply some business logic to the values stored in the JCR before outputting them to the page.

  1. Open the file HelloWorldModel.java , which is the Sling Model used with the HelloWorld component.
    <code>/aem-guides-wknd.core/src/main/java/com/adobe/aem/guides/wknd/core/models/HelloWorldModel.java
    
    
  2. Add the following lines to the HelloWorldModel class to map the values of the component's JCR properties greeting and text to Java variables:
    ...
    @Model(adaptables = Resource.class)
    public class HelloWorldModel {
    
        ...
    
        @ValueMapValue(injectionStrategy=InjectionStrategy.OPTIONAL)
        protected String greeting;
    
        @ValueMapValue(injectionStrategy=InjectionStrategy.OPTIONAL)
        protected String text;
    
            @PostConstruct
            protected void init() {
                ...
    
    
  3. Add the following method getGreeting() to the HelloWorldModel class, that returns the value of the property named greeting . This method adds the additional logic to return a String value of "Hello" if the property greeting is null or blank:
    /***
    *
    * @return the value of greeting, if null or blank returns "Hello"
    */
    public String getGreeting() {
        return StringUtils.isNotBlank(this.greeting) ? this.greeting : "Hello";
    }
    
    
  4. Add the following method getTextUpperCase() to the HelloWorldModel class, that returns the value of the property named text . This method transforms the String to all upperCase characters.
        /***
        *
        * @return All caps variation of the text value
        */
    public String getTextUpperCase() {
        return StringUtils.isNotBlank(this.text) ? this.text.toUpperCase() : null;
    }
    
    
  5. Update the file helloworld.html at aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/components/content/helloworld/helloworld.html to use the newly created methods of the HelloWorld model:
    <div class="cmp-helloworld" data-sly-use.hello="com.adobe.aem.guides.wknd.core.models.HelloWorldModel">
        <h1 data-sly-test="${hello.textUpperCase}">${hello.greeting} ${hello.textUpperCase}</h1>
        <pre>
        HelloWorldModel says:
        ${hello.message}
        </pre>
    </div>
    
    
  6. Deploy the changes to a local instance of AEM using the Eclipse Developer plugin or using your Maven skills.

Client-Side Libraries

Client-Side Libraries, clientlibs for short, provides a mechanism to organize and manage CSS and JavaScript files necessary for an AEM Sites implementation. Client-side libraries are the standard way to include CSS and JavaScript on a page in AEM.
Next, we will include some CSS styles for the HelloWorld component in order to understand the very basics of client-side libraries.

Below are the high level steps performed in the above video.
  1. beneath /aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/components/content/helloworld create a new node named clientlibs with a node type of cq:ClientLibraryFolder .
  2. Create a folder and file structure like the following beneath clientlibs
    /helloworld
            /clientlibs
                /css/helloworld.css
                /js/helloworld.js
                +js.txt
                +css.txt
    
    
  3. Populate helloworld/clientlibs/css/helloworld.css with the following:
    .cmp-helloworld h1 {
        color: red;
    }
    
    
  4. Populate helloworld/clientlibs/css.txt with the following:
    #base=css
    helloworld.css
    
    
  5. Populate helloworld/clientlibs/js/helloworld.js with the following:
    console.log("hello world!");
    
    
  6. Populate helloworld/clientlibs/js.txt with the following:
    #base=js
    helloworld.js
    
    
  7. Update the clientlibs node properties to include the following two properties:
    Name
    Type
    Value
    categories
    String
    wknd.base
    allowProxy
    Boolean
    true
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root
        xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
        xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:ClientLibraryFolder"
        categories="wknd.base"
        allowProxy="{Boolean}true"/>
    
    
  8. Deploy the changes to a local instance of AEM using the Eclipse Developer plugin or using your Maven skills.

Congratulations!

Congratulations, you have just learned the basics of component development in Adobe Experience Manager!

Next Steps

Get familiar with Adobe Experience Manager pages and templates in the next chapter Pages and Templates . Understand how Core Components are proxied into the project and learn advanced policy configurations of editable templates to build out a well-structured Article Page template.
View the finished code on GitHub or review and deploy the code locally at on the Git brach component-basics/solution .
  1. Clone the github.com/adobe/aem-wknd-guides repository.
  2. Check out the component-basics/solution branch