Use Sling Model with Sightly in AEM

The focus of this tutorials is to understand what are sling models , how to use Sling Model with Sightly in AEM, how to automatically map values from jcr node properties  to java resource. I have tried to cover all the areas that are required to use sling models in sightly in this tutorial with the help of a simple example.

After completing this tutorial you will have a better understanding about:-

Sling Models


Many Sling projects want to be able to create model objects – POJOs which are automatically mapped from Sling objects, typically resources, but also request objects.
Sometimes these POJOs need OSGi services as well.

In simple terms Sling Models are simple POJO classes which are mapped automatically with Sling Objects (resource, request objects..) and allow us to access jcr node property values directly into java classes.

Advantages of using Sling Models

  • Pure POJO classes.
  • Entirely annotation driven(Need to write less code).
  • Can adapt multiple objects –  – minimal required Resource and SlingHttpServletRequest
  • OOTB, support resource properties (via ValueMap), SlingBindings, OSGi services, request attributes
  • Support both classes and interfaces.
  • Plugabble.
  • Work with existing Sling infrastructure (i.e. not require changes to other bundles).

Sling Model Annotation

Creating an adaptable class by annotation


First step during creation of sling model is to adapt the POJO class to a Object type( Resource, Request etc..)

// Traditional way of adapting to resource using java class
Resource r = getResource();
return r.adaptTo(customClassName.class);

// Creating adaptable resource class using sling annotation
@Model(adaptables = Resource.class)
public class customClassName{
...
}

Click Here For complete list of Sling Annotations

Injecting properties in POJO class


Lets understand it with the help of below code:-

// Traditional way to getting values from jcr nodes in Java Class.
@Component
@Service
@Properties({
@Property(name = "adaptables", value = {"Resource" }),
@Property(name = "adapters", value = {"YourCustom" })
})

// Retrieving vales from jcr node through inject in Sling Model  
@Model(adaptables = Resource.class)
public class slingModelExample {
@Inject // email property is always looked from Resource( after adapting to ValueMap), if this property value 
is not present then it returns null. If this property is in itself not available then it throws exception.
private String email;
@Inject @Optional // It is not mandatory to have firstname property in Resource.
private String firstName;
// Use @Named if jcr node property name is different than class variable. 
use @Default if you want to assign default values, If empty then assign default value as 'NA'
@Inject @Named("surname") @Default(values="NA")
private String lastName;
}
@Inject // OSGi Service
private Externalizer externalizer;

//@PostConstructor annotation defines that this method will run after injecting all field 
@PostConstruct
protected void init() {
// gets executed after the class is created and all variables are injected
}

Note:- We can also inject OSGI services.

So, just to summarize above code:-

  • @Inject :- email property is always looked from Resource( after adapting to ValueMap), if this property value is not present then it returns null. If this property is in itself not available then it throws exception.
  • @Inject @Optional :- It is not mandatory to have firstname property in Resource.
  • @Named :- Use  it if jcr node property name is different than class variable.
  • @Default :- use it if you want to assign default values, If empty then assign default value as ‘NA’.
  • @PostConstructor:-  annotation defines that this method will run after injecting all field.

Use Sling Model with Sightly:-

In our last post, we have seen how to create aem multi module project. In this tutorial, i am going to use the sling model and hello world component that is created by AEM Multi Module project. You can create sling model in your existing project also. For doing this you need to check two things.

  • Correct dependencies for sling model in your project pom.xml.
  •  <dependency>
    <groupId>org.apache.sling</groupId>
    <artifactId>org.apache.sling.models.api</artifactId>
    </dependency>

Note:- You can also verify dependencies from depfinder tool. Search for org.apache.sling.models.annotations.Model dependency. If it is available then you are good else add this dependency in pom.

find sling model dependency in aem depfinder

  • Add your java package information in your maven-bundle plugin in pom.xml of respective module.
    add java package dependencies to java package pom

What will happen if i don’t add these dependencies? 

If you don’t add java packages to your pom.xml then maven wont add these packages into header entry of your bundle manifest file. Due to which  these classes will not behave as sling models and will work as simple java classes.

Note:- If you miss to add your sling model package in pom.xml then it wont through any error  in error.log file.

Create Sling models and use them on components using Sightly


Lets explore the sling model that we have created in Previous tutorial.

  • Go to Crxde.
  • Go to hello world component (/apps/aemtutorials/components/content/helloworld).

Below figure will show how we are passing the values from jcr node to sling model and retrieving it in our hello world component script.

adapt node values to pojo class aem

Now lets add one more field in model and retrieve its value in sightly. We have a text property in dialog box lets add it also to sling model and get it from there to hello world.html.

  • Open eclipse go to HelloWorldModel.java.
    • Create a new string variable by name text
    • Add @Inject annotation on it.
    • Add @Default annotation on it, in case it is empty.
      add inject annotation in sling model
  • Open helloWorld.html file
    • Add below code to helloWorld.html file.
      
      
      <pre data-sly-use.refObject="org.training.aemcq5tutorials.core.models.HelloWorldModel">
      ${refObject.text}
      </pre>
      
      
    • Add ${refObject.text} to access text value from sling model.
      Note:- While accessing a method we remove get from it and change the first uppercase letter to small case.
      access sling model values in sightly
  • Build the code using command prompt.
  • Open command prompt (cmd) and go to project pom.xml location.
  • Run below command
 mvn clean install -P aemcq5tutorials-author 

build maven project aem

Testing Sightly Component

  • Go to Site Admin.
  • Create a page Home under english, by using aem content template.
    testing helloworld component aem
  • Double click and open Home page.
  • Drag and drop hello world component from sidekick to parsys.
  • As we have not provided and value to text component it will print default text.
    getting default values from sling model to sightly aem
  • Right click and edit helloworld component and add text “Welcome to Training” and click OK.
    get values from sling model to sightly

Hope this tutorial has cleared you basic doubts about how to use sling models with sightly in aem. If you are still facing any issue, please drop a comment below.

Spread the love
  •  
  •  
  •  
  •  
  •  
  •  

Leave a Reply

Your email address will not be published. Required fields are marked *