蜜豆视频

Component Basics component-basics

In this chapter, let鈥檚 explore the underlying technology of an 蜜豆视频 Experience Manager (AEM) Sites Component through a simple HelloWorld example. Small modifications are made to an existing component, covering topics of authoring, HTL, Sling Models, Client-side libraries.

Prerequisites prerequisites

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

The IDE used in the videos is and the plugin.

Objective 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 are going to build what-build

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

Chapter Starter Project starter-project

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

NOTE
If you successfully completed the previous chapter, you can reuse the project and skip the steps for checking out the starter project.

video poster

Open a new command-line terminal and perform the following actions.

  1. In an empty directory, clone the repository:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd.git --branch tutorial/component-basics-start --single-branch
    
    note note
    NOTE
    Optionally, you can continue using the project generated in the previous chapter, Project Setup.
  2. Navigate into the aem-guides-wknd folder.

    code language-shell
    $ cd aem-guides-wknd
    
  3. Build and deploy the project to a local instance of AEM with the following command:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage
    
    note note
    NOTE
    If using AEM 6.5 or 6.4, append the classic profile to any Maven commands.
    code language-shell
    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    
  4. Import the project into your preferred IDE by following the instructions to set up a local development environment.

Component Authoring component-authoring

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

video poster

Transcript

All right, so now we鈥檙e going to create a new page. So, from the AEM Sites console, I鈥檓 just going to navigate under weekend US. And then under the homepage, EN, we鈥檒l create a new page and we鈥檙e just going to choose the content page template. And for the title, I鈥檒l just call this component basics.

Then we can go ahead and create our page and open it up.

Now all AEM pages that are enabled for authoring. We鈥檒l have this drop zone otherwise known as layout container. And this is the area of the page that a content author can add new components. So, open up the side panel and we鈥檒l browse to the available components.

And I鈥檓 just going to select the hello world component. The hello world component is included by the archetype really just for illustration purposes in order to gain an understanding of how components work. So, you can see that it鈥檚 already outputting some information as soon as we add it to the page. And this is a result of some backend code that we鈥檒l look at later in the tutorial. Now that I鈥檝e added the component, we can configure it by selecting the component and clicking the wrench icon. In order to make components reusable, almost all of them have configurations. In this case, it鈥檚 a simple text field. So, I鈥檒l enter some information in the text field and then save the changes by clicking done. Notice that the component now renders a simple message. This example shows how a component can take user entered information and render it as part of the page.

Let鈥檚 add a second hello world component.

And I鈥檒l configure this one, except this time let鈥檚 enter a different message to be displayed. So, we鈥檒l call it hello world two. And then we can see the result. So that鈥檚 an example of how dialogues facilitate authoring and how you can reuse the same component on the same page but with different outputs. Now let鈥檚 take a look at the JCR or the Java content repository and see how the text properties of these components are persisted.

Now, an easy way to do this is to switch into developer mode. And developer mode is a tool intended to be used really just on a local environment. And it provides a lot of useful information in diagnostics of all of the components that currently make up the page. So, you鈥檒l notice that in this side panel, there鈥檚 a lot more components listed here than there are in the content tree.

And if we select the hello world component it will automatically expand the tree and show us that instance of the component.

And so, you can see we鈥檝e got a responsive grid and then we鈥檝e got our hello world component. Both of them listed here.

And if we select this button to view details it鈥檒l actually show us the content path to this exact component.

And if we click that, that鈥檚 going to open up CRXDE Lite which is a view into the backend JCL repository of AEM.

And notice that we can see both the hello world components And it鈥檚 under our component basics page.

In the text, you can see that text property that we listed here, but that鈥檚 really the only data that鈥檚 stored. And if we click our second hello world component, you can see the second text property.

So where does the rest of the rendering information come from? Well, it actually gets derived from this line string resource type which points to weekend components, content, hello world. And so that is the actual rendering script that鈥檚 used to render the component on the page.

So, let鈥檚 take a look at where that rendering script lives. Now, since this is code it鈥檚 actually going to live under the apps folder. So, in CRXDE Lite, if you expand the apps folder under weekend components, content, and hello world you can actually see this is the hello world code component and you can see the hello world.HTML file in there. And so, this is the actual rendering script written in HTML. And this is responsible for outputting all of the content that you see when you add that component to the page. And that鈥檚 what we鈥檙e going to look at next. -

Below are the high-level steps performed in the above video.

  1. Create a 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 from /apps/wknd/components/content/helloworld.

HTL (HTML Template Language) and Dialogs htl-dialogs

HTML Template Language or HTL is a light-weight, server-side templating language used by AEM components to render content.

Dialogs define the configurations available that can be made for a component.

Next let鈥檚 update the HelloWorld HTL script to display an extra greeting before the text message.

video poster

Below are the high-level steps performed in the above video.

  1. Switch to the IDE and open the project to the ui.apps module.

  2. Open the helloworld.html file and update the HTML Markup.

  3. Use the IDE tools like to synchronize the file change with the local AEM instance.

  4. Return to the browser and observe the component render has changed.

  5. Open the .content.xml file that defines the dialog for the HelloWorld component at:

    code language-plain
    <code>/aem-guides-wknd/ui.apps/src/main/content/jcr_root/apps/wknd/components/helloworld/_cq_dialog/.content.xml
    
  6. Update the dialog to add an extra textfield named Title with a name of ./title:

    code language-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"
        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">
                        <title
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                            fieldLabel="Title"
                            name="./title"/>
                        <text
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                            fieldLabel="Text"
                            name="./text"/>
                    </items>
                </column>
            </items>
        </content>
    </jcr:root>
    
  7. Reopen the file helloworld.html, which represents the main HTL script responsible for rendering the HelloWorld component from below path:

    code language-plain
        <code>/aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/components/helloworld/helloworld.html
    
  8. Update helloworld.html to render the value of the Greeting textfield as part of an H1 tag:

    code language-html
    <div class="cmp-helloworld" data-cmp-is="helloworld">
        <h1 class="cmp-helloworld__title">${properties.title}</h1>
        ...
    </div>
    
  9. Deploy the changes to a local instance of AEM using the developer plugin or using your Maven skills.

Sling Models sling-models

Sling Models are annotation driven Java鈩 鈥淧OJOs鈥 (Plain Old Java鈩 Objects) that facilitate the mapping of data from the JCR to Java鈩 variables. They also provide several other niceties when developing in the context of AEM.

Next, let鈥檚 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.

video poster

  1. Open the file HelloWorldModel.java, which is the Sling Model used with the HelloWorld component.

    code language-plain
    <code>/aem-guides-wknd.core/src/main/java/com/adobe/aem/guides/wknd/core/models/HelloWorldModel.java
    
  2. Add the following import statements:

    code language-java
    import org.apache.commons.lang3.StringUtils;
    import org.apache.sling.models.annotations.DefaultInjectionStrategy;
    
  3. Update the @Model annotation to use a DefaultInjectionStrategy:

    code language-java
    @Model(adaptables = Resource.class,
       defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
       public class HelloWorldModel {
       ...
    
  4. Add the following lines to the HelloWorldModel class to map the values of the component鈥檚 JCR properties title and text to Java鈩 variables:

    code language-java
    ...
    @Model(adaptables = Resource.class,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
    public class HelloWorldModel {
    
        ...
    
        @ValueMapValue
        private String title;
    
        @ValueMapValue
        private String text;
    
        @PostConstruct
        protected void init() {
            ...
    
  5. Add the following method getTitle() to the HelloWorldModel class, that returns the value of the property named title. This method adds the additional logic to return a String value of 鈥淒efault Value here!鈥 if the property title is null or blank:

    code language-java
    /***
    *
    * @return the value of title, if null or blank returns "Default Value here!"
    */
    public String getTitle() {
        return StringUtils.isNotBlank(title) ? title : "Default Value here!";
    }
    
  6. Add the following method getText() to the HelloWorldModel class, that returns the value of the property named text. This method transforms the String to all uppercase characters.

    code language-java
        /***
        *
        * @return All caps variation of the text value
        */
    public String getText() {
        return StringUtils.isNotBlank(this.text) ? this.text.toUpperCase() : null;
    }
    
  7. Build and deploy the bundle from the core module:

    code language-shell
    $ cd core
    $ mvn clean install -PautoInstallBundle
    
    note note
    NOTE
    For AEM 6.4/6.5 use mvn clean install -PautoInstallBundle -Pclassic
  8. 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.

    The HelloWorld model is instantiated for this component instance via the HTL directive: data-sly-use.model="com.adobe.aem.guides.wknd.core.models.HelloWorldModel", saving the instance to the variable model.

    The HelloWorld model instance is now available in the HTL via the model variable using the HelloWord. These methods invocations can use shortened method syntax for example: ${model.getTitle()} can be shorted to ${model.title}.

    Similarly, all HTL scripts are injected with global objects that can be accessed using the same syntax as the Sling Model objects.

    code language-html
    <div class="cmp-helloworld" data-cmp-is="helloworld"
        data-sly-use.model="com.adobe.aem.guides.wknd.core.models.HelloWorldModel">
        <h1 class="cmp-helloworld__title">${model.title}</h1>
        <div class="cmp-helloworld__item" data-sly-test="${properties.text}">
            <p class="cmp-helloworld__item-label">Text property:</p>
            <pre class="cmp-helloworld__item-output" data-cmp-hook-helloworld="property">${properties.text}</pre>
        </div>
        <div class="cmp-helloworld__item" data-sly-test="${model.text}">
            <p class="cmp-helloworld__item-label">Sling Model getText() property:</p>
            <pre class="cmp-helloworld__item-output" data-cmp-hook-helloworld="property">${model.text}</pre>
        </div>
    </div>
    
  9. 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

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.

The ui.frontend module is a de-coupled project that is integrated into the build process. This enables the use of popular front-end libraries like Sass, LESS, and TypeScript. The ui.frontend module is explored in more depth in the Client-Side Libraries chapter.

Next, update the CSS styles for the HelloWorld component.

video poster

Below are the high-level steps performed in the above video.

  1. Open a terminal window and navigate into the ui.frontend directory

  2. Being in ui.frontend directory run the npm install npm-run-all --save-dev command to install the node module. This step is required on Archetype 39 generated AEM project, in upcoming Archetype version this is not required.

  3. Next, run the npm run watch command:

    code language-shell
    $ npm run watch
    
  4. Switch to the IDE and open the project to the ui.frontend module.

  5. Open the file ui.frontend/src/main/webpack/components/_helloworld.scss.

  6. Update the file to display a red title:

    code language-scss
    .cmp-helloworld {}
    .cmp-helloworld__title {
        color: red;
    }
    
  7. In the terminal, you should see activity indicating that the ui.frontend module is compiling and syncing the changes with the local instance of AEM.

    code language-shell
    Entrypoint site 214 KiB = clientlib-site/site.css 8.45 KiB clientlib-site/site.js 206 KiB
    2022-02-22 17:28:51: webpack 5.69.1 compiled successfully in 119 ms
    change:dist/index.html
    + jcr_root/apps/wknd/clientlibs/clientlib-site/css/site.css
    + jcr_root/apps/wknd/clientlibs/clientlib-site/css
    + jcr_root/apps/wknd/clientlibs/clientlib-site/js/site.js
    + jcr_root/apps/wknd/clientlibs/clientlib-site/js
    + jcr_root/apps/wknd/clientlibs/clientlib-site
    + jcr_root/apps/wknd/clientlibs/clientlib-dependencies/css.txt
    + jcr_root/apps/wknd/clientlibs/clientlib-dependencies/js.txt
    + jcr_root/apps/wknd/clientlibs/clientlib-dependencies
    
  8. Return to the browser and observe that the title color has changed.

    Component Basics update

Congratulations! congratulations

Congratulations, you have learned the basics of component development in 蜜豆视频 Experience Manager!

Next Steps next-steps

Get familiar with 蜜豆视频 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 or review and deploy the code locally at on the Git branch tutorial/component-basics-solution.

recommendation-more-help
b2a561c1-47c0-4182-b8c1-757a197484f9