April 10, 2020
Estimated Post Reading Time ~

Creating your first Component in AEM

Suppose you need to create a website for cute and adorable teddy bears 🐻. In this site, on some web pages, there has to be an image of a teddy bear along with its title, some descriptive text, and price.
As you may have guessed, a good way to do it to create a small entity having these fields and which is configurable and can be reused on these pages.

Here to our rescue come the AEM Components. A component as its name suggests a reusable entity that can be used anywhere on our website. As per our requirement, we can configure the same component differently on different pages (different look with the same feel). A typical AEM page is composed of many such components.

Components are the building blocks of pages. A component usually contains a JSP or HTML file that contains the HTML markup and maybe some business logic for that component.

Note: Adobe recommends HTL (HTML Template Language) to be used for markup instead of JSP.

In this post, we will be creating one video component that takes video id from YouTube or Vimeo and plays the video on our page. Let's get started.

Creating the component dialog

For using the component, we first need to create a proper dialog structure in AEM
  • Open CRXDE and move to your project under /apps.
  • Right-Click on the desired folder, then Create..., then Create Component... and configure as per the below screenshot and save and Save All...
Create a Component
  • Create nodes and properties under the component node as per the following XML file
<?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="Video Component"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/foundation/container">
        <layout
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/foundation/layouts/tabs"
            type="nav"/>
        <items jcr:primaryType="nt:unstructured">
            <tab
                jcr:primaryType="nt:unstructured"
                jcr:title="Properties"
                sling:resourceType="granite/ui/components/foundation/container">
                <layout
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
                <items jcr:primaryType="nt:unstructured">
                    <columns
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/foundation/container">
                        <items jcr:primaryType="nt:unstructured">
                            <title
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                class="field-whitespace"
                                fieldDescription="Please enter title of the video"
                                fieldLabel="Title"
                                name="./title"/>
                            <videoLink
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                class="field-whitespace"
                                fieldDescription="Enter the valid external webm video link"
                                fieldLabel="External Link"
                                name="./link"
                                required="{Boolean}true"/>
                            <play
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                fieldDescription="Enter the text for Play button"
                                fieldLabel="Play Button Text"
                                name="./play"
                                required="{Boolean}true"/>
                            <pause
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                fieldDescription="Enter the text for Pause button"
                                fieldLabel="Pause Button Text"
                                name="./pause"
                                required="{Boolean}true"/>
                        </items>
                    </columns>
                </items>
            </tab>
        </items>
    </content>
</jcr:root>
  • Now rename the video.jsp file to video.html and paste the below code in it
<style>
.first {
transition: 0.30s;
-webkit-transition: 0.30s;
-moz-transition: 0.30s;
-o-transition: 0.30s;
-ms-transition: 0.30s;
font-family: verdana;
text-decoration: none;
color: white;
background-color: #81e55c;
padding: 9px;
border-radius: 10px;
box-shadow: 2px 2px 2px black;
}

.first:hover {
background-color: #a5f488;
}

.first:active {
box-shadow: 0px 0px 0px black;
}

.second {
transition: 0.30s;
-webkit-transition: 0.30s;
-moz-transition: 0.30s;
-o-transition: 0.30s;
-ms-transition: 0.30s;
font-family: verdana;
text-decoration: none;
color: white;
background-color: #c0362c;
padding: 9px;
border-radius: 10px;
box-shadow: 2px 2px 2px black;
}

.second:hover {
background-color: #db7f7f;
}

.second:active {
box-shadow: 0px 0px 0px black;
}

video {
-webkit-transition: 0.60s;
-moz-transition: 0.60s;
-o-transition: 0.60s;
-ms-transition: 0.60s;
border: 1px solid black;
box-shadow: 0px 0px 10px black;
}

video:hover {
box-shadow: 0px 0px 20px black;
}
</style>

<script>
window.onload = function() {
var video = document.getElementById('my-video');
var play = document.getElementById('play');
var pause = document.getElementById('pause');

// associate functions with the 'onclick' events
play.onclick = playVideo;
pause.onclick = pauseVideo;

function playVideo(e) {
e.preventDefault();
video.play();
}

function pauseVideo(e) {
e.preventDefault();
video.pause();
}
}
</script>

<body bgcolor="${properties.bgColor}">
<center>
<video style="background-color: ${properties.bgColor" preload="auto"
width="480" height="270" id="my-video">
<source src="${properties.link}">
</video>
<br> <br>
<div>
<a class="first" href="#" id="play">${properties.play}</a> <a
class="second" href="#" id="pause">${properties.pause}</a>
</div>
</center>
  • This is a simple file where we have applied styling and added some JavaScript logic to run the component. If you look closely we are using properties.titleproperties.linkproperties.play and properties.pause in our HTML code. 
  • Actually, we are configuring the values from the edit dialog (shown below) and the values we save are getting displayed dynamically in the markup using the property object.
Edit Dialog
  • The values of fields in JCR are saved using the name class in each field node. The value of the name property is used to access the value in the JCR. For e.g. to access the External Link field value, we have to use property.link. 
Node Properties
  • Once you save the dialog, you will see the output as - 
Video Component Output

Conclusion

Congratulations!! 🙋 you have created your first AEM Component which displays the video as per the given WebM link. I hope you enjoyed this post.

You can find the complete code of this project on my GitHub. Feel free to fork or open issues, if any.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.