Headless and Experience Fragment

(910) 367-5676

For those who start developing in AEM recently has the luxury of using sling model or AEM WCM Use API. I started with AEM about 7 years ago with version 5.4 where it was called CQ, and sling model was nowhere to be seen. We would use pure JSP to access resource properties through the sling define objects. That wasn’t too pretty to look at. Basically, you will mingle your HTML code with <% %> JSP and a component can be as confusing as Sudoku. JSTL was, later on, introduced to me and things are looking brighter, but coming from an MVC model background I would prefer a Model, View, and Controller. As I advance through my career I have seems different custom implementation of custom MVC that get bake into AEM/CQ, but none of them are as robust as Sling model, and before I lost my train of thought let me go right into the topic.

What is sling model?

It’s a POJOs that is capable of automatically mapped sling object such as resources, sling request.

What does sling model achieve?

Sling model achieves that MVC model which is needed in AEM, and it achieves that through standard annotation.

Let say business need you to create a promotion component that required heading, sub-heading, short description, image and a link which link can be a button. The first thing you would do will probably create a dialog where the author can enter all those required fields, and as for each field in that dialog will typically map to a name and that name will be the key to retrieve your value. You could do something like ${properties.<key>} in your HTL (sightly) file, but what happens if you need to do some business logic before rendering to the end user. You can create a sling model and @Inject each value into your sling model and use @PostConstruct to edit those value before render to your end user.

@Model(adaptable=Resource.class)
public class promotion{

@Inject
String heading;

@Inject
String subHeading;

@Inject
String link;

@Inject
String image;

@Inject
String shortDescription;

@Inject
ResourceResolver resourceResolver;

@PostConstruct
protected void init(){
/ this method will get call after every variable are injected
link = StringUtils.isNotEmpty(link)?resourceResolver.map(link):"#";
}

/make sure you create getter methods to expose whichever variable you need

}

Let me explain what’s going on the above code. So @Model is a sling model annotation where it said a Resource object can be adaptTo this particular object. There are other attributes you can add to the @Model annotation to further define your sling model. Now each @Inject annotation is basically injecting value into that field base on each name field you define in your dialog. For example, let said your title field has a name property of heading then that value will be injected into your heading variable and same go for other variables. Now let said you need to modify the link before showing to the end user you can add a @PostConstruct which get invoked when all the variables have been injected. This provide an entry point so you can modified your variables. Below I will show you how to use that sling model in your HTL

let said your component is call promotion, so your htl file will be promotion.html

<div data-sly-use.model="com.yong.demo.promotion">

<h1><a href="${model.link @context='uri'}">${model.heading}</a></h1>

</div>

data-sly-use.model basically try to adapt a resource into promotion object and assign it to the model variable and you can access each field variable by doing model.<variable_name> @context=uri mean that the value needs to Validates URI for writing as an href or src attribute value, outputs nothing if validation fails. More different context can be fine (254) 856-6235