May 15, 2020
Estimated Post Reading Time ~

AEM 6.3: Developing with the new Core Components

The new AEM 6.3 brings with it the WCM Core Components Library, a set of reusable and production-ready components. Learn how to take advantage of them.

In the last couple of years developing components for AEM has become more accessible. We got HTL (formerly Sightly) and Sling models, and TouchUI became more mature and stable. Still, when it was time to get your hands dirty it was difficult to find good examples of how things should be implemented. Geometrixx (and their spin-offs like outdoors or media) had been for a very long time the standard reference of how components should be implemented.

Unfortunately, as you might know, Geometrixx in many cases was more an example of how you should NOT do things rather than how to do them. Luckily for us, AEM 6.3 brings in the Adobe WCM Core Components and a new implementation of the We.Retail demo site, which will serve as an actual showcase of good component development practices. As a side note, Geometrixx has been completely removed on AEM 6.3.

What are the Core Components?
The Adobe WCM Core Components are a set of basic but feature complete components developed by Adobe that are meant to be easily reused and expanded upon for AEM projects. Some advantages are:

100% written in HTL. No awful JSPs that are hard to read and expand.
Compatible with AEM 6.3 only. You might be able to make them run in older versions, but no promises are made.
Back-end provided by Sling Models. What's even better is that it uses all the new features present in Sling Models 1.3.0 (more of that later on this post).
Basic but feature complete. If your use case is simple you might not need to change anything to use them!
Open Source. Its source code it's stored in github. Adobe is trying to build up a community and will accept improvements and patches for the project.
Versioning separate from AEM. AEM can be upgraded easily without upgrading your dependency in the core models or models can be upgraded without the need to upgrade AEM.
Components are versioned. Multiple versions of the same component can be installed in a single AEM instance and different components rely on whichever implementation is best for them.

Note about deployment: The Core Components are not part of the AEM 6.3 installation, but you might find them installed since they are part of the We.Retail packages. If you use the production-ready "nosamplecontent" runmode they will not be installed. I recommend deploying them along with your project packages.

I'm not going to go deep into which exact components are available since you can just go the project and check out yourself. Instead, I will give a short introduction of how they can be used in your projects. Example: a simple extension

Let's create a small requirement and see how we can use the Core Components. Let's start with a component that allows the editor to create titles for sections of a web page. The title text should be editable by the author and should always use the H1 HTML Tag.

Choose a component to extend
In our case this is very straight forward, there is a Title component that has features very similar to what we need. The component by default allows you to choose the type of tag that will be used to render the title. We need to eliminate this possibility.

First of all, as with other provided components like the ones on the AEM foundation, you should not rely directly on them. That means that editors will not directly drag and drop the Core Components into pages. Instead, you should create new components that extend the Core Components and modify whatever you need (if needed). This is nothing new and has been a standard good practice for a long time.

Create the new component
Create a folder under apps to put your components (I used /apps/netcentric/example/components).
Create a node with type cq:Component with the sling:resourceSuperType set to core/wcm/components/title/v1/title and a componentGroup of your choice.
Now we should allow it on a page. Edit the template in http://localhost:4502/editor.html/conf/we-retail/settings/wcm/templates/hero-page/structure.html and edit the policy for the Layout Container. Add your component to the list of allowed components.
Go to http://localhost:4502/editor.html/content/we-retail/us/en/women.html and try adding your component into the Layout Container. Try playing around with the component to see how it works.

Modify behavior
Now the fun part begins. We need to remove functionality instead of adding it or modifying it, so it should be straight forward.

The first thing we should do is to adapt the dialog. Fortunately, the Sling Resource Merger is completely leveraged so we can use it to hide part of the original dialog:
Create a cq:dialog node below your custom title component.
Create a structure that mimics the original dialog. You can create it manually, or copy the original and delete whatever you don't need.
Create aproperty sling:hideChildren below /apps/netcentric/example/components/title/cq:dialog/content/items/column/items , set it to types. This will hide the types field from the dialog.

Go back to the editor page and try it out. The type dropdown should be gone.
Try achieving the same for the design dialog (i.e. the cq:design_dialog node).
Finally, copy the title.html from the original component into yours and edit it. Remove the data-sly-element="${title.type}" from the H1 tag.

Done! As you can see this was incredibly simple.

Example 2: some back-end changes
After using your component for a while, your client tells you that the feature in which the page title is used by default in the component is no good for them. Instead, they want it to show the navigation title by default and the page title as a fallback and the title as a final fallback for both.

This will require us to implement a new backend for our component.

If you examine the title.html file, you'll see that it imports com.adobe.cq.wcm.core.components.models.Title. This is actually an interface, not an implementation. The actual implementation is not exported by the Core Components bundle, but since it is open-source, we can have a look at it.
Let's create our own implementation of the Title interface.

Disclaimer: These instructions assume you are able to create, compile and deploy an OSGi bundle. If you do not know how to do this, find out and come back when you do.

Firstly, we should create in a bundle a new implementation of the Title Interface. It has only two methods, so it is straight forward. The interesting part comes in the @Model annotation. In Sling Models 1.3.0 (included in AEM 6.3) it is possible to define precisely to which resource types our implementation should be bound to. See this demo implementation:

Title
@Model(adaptables=SlingHttpServletRequest.class,adapters=Title.class ,resourceType="netcentric/example/components/title")
public class CustomTitle implements Title {
@ScriptVariable
private Page currentPage;
@ValueMapValue( name = "jcr:title",injectionStrategy=InjectionStrategy.OPTIONAL)
private String title;
@Override
public String getText() {
return title;
}
@PostConstruct
public void init(){
if(StringUtils.isNotBlank(title)){
return;
}
if(StringUtils.isNotBlank(currentPage.getNavigationTitle())){
title=currentPage.getNavigationTitle();
return;
}
if(StringUtils.isNotBlank(currentPage.getPageTitle())){
title=currentPage.getPageTitle();
return;
}
title= currentPage.getTitle();
}
@Override
public String getType() {
return null; //not needed
}
}

Take a close look at the @Model annotation. The type parameter allows us to define the interface from which the model should be adapted, and the resourceType parameter allows us to bind our implementation to a specific component type. That way our implementation will not interfere with other components expanding on the core Title component.

Compile and deploy your bundle. Now your custom backend Title should be preferred over the default one.

Conclusion
We have briefly examined how the new Adobe Core Components allow us to easily expand them and modify them as needed. We have very easily created customizations both in the backend and the frontend of the component thanks to HTL, the Sling Resource Merger and Sling Models.



By aem4beginner

No comments:

Post a Comment

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