Wednesday, November 5, 2014

How to use Sling Models in CQ5.6

Use Case: Use Sling Model in CQ5.6

Background: Sling model http://sling.apache.org/documentation/bundles/models.html brings powerful way of mapping your resources to Java Objects (Beans) . It is supported OOTB in CQ6 however we can use it in CQ5.6 as well.

Solution:

First add sling models as dependency in your code (In Parent pom using dependency manager is preferred)

Then update your reactor pom (Which actually creates your CQ package using content-package-maven-plugin) you need to add following as dependency and then embed them in to your project (If install path for system is not present you can use any other path you want)

Thats it .. Models are available as service in your OSGI environment.



 To use model go ahead and create your own bundle and them add these as dependency. You should be able to write, deploy and run code against model. Note that you might have to make these model available to osgi using Sling-Model-Packages



Once model is deployed correctly you should be able to see them under sling-model tab in status in felix console or by going to HOST:PORT/system/console/status-slingmodels



Some example code using models

Some common How to

How can I inject services in Sling Model

by using annotation @OSGIService Or Using Injector @Inject @Source("osgi-service") 

Example:

@OSGIService
MyService myService

@Inject @Source("osgi-service")
MyService myService


How Can I Inject Sling Object in Sling Model

by using annotation @SlingObject Or Using Injector @Inject @Source("sling-object") 

Example:

@SlingObject
ResourceResolver resourceResolver

@Inject @Source("sling-object")
ResourceResolver resourceResolver


How Can I get access to property if adapting through Sling Request

If you are adapting your model to sling request you might not have access to property by just doing @Inject. You have to use @Via in that case. Note that you can use all other annotation here like @Named and all. Here is example

@Model(adaptables=SlingHttpServletRequest.class)
public interface MyModel { 
 
    @Inject @Via("resource")
    String propertyName;
}

How Can I use Sling Tag Library with Sling Model

You can use <sling:adaptTo ... /> or ${sling:adaptTo ...} as mentioned in https://sling.apache.org/documentation/bundles/models.html and https://sling.apache.org/documentation/bundles/sling-scripting-jsp-taglib.html .In 5.6 you might have to change global.jsp to use
<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling" %>
instead of
<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %>

How Can I provide default value to property in Sling Model

By using @Default Annotation . Here is example

A default value can be provided (for Strings & primitives) and Array:
@Model(adaptables=Resource.class)
public class MyModel {

    @Inject @Default(values="defaultValue")
    private String name; 
    @Inject @Default(intValues={1,2,3,4})
    private int[] integers; 
}

How Can I inject child resource as Model in Sling Model 

This can be done by Injecting a model in other model class. Here is example


@Model(adaptables=Resource.class)
public interface MyModel {

    @Inject
    ImageModel getImage();
}

@Model(adaptables=Resource.class)
public interface ImageModel {

    @Inject
    String getPath();
}

When a resource is adapted to MyModel, a child resource named image is automatically adapted to an instance of ImageModel

Note: Sling model version number can change as it evolves in future. Make sure that you update model dependencies version accordingly. You can also use Sling testing framework to test sling model which is pretty cool as well. There is also an example of deployable Model package https://github.com/Adobe-Consulting-Services/com.adobe.acs.bundles.sling-models which you can use.

As usual feel free to give your comment and feedback and let me know if you want me to add something else here.


7 comments:

  1. Hey, I did all as u mentioned here, but still cant get properties in jsp, what can be wrong?

    ReplyDelete
    Replies
    1. Are you getting any error while accessing model in Jsp ? How do you access it in jsp ?

      Delete
    2. This comment has been removed by the author.

      Delete
    3. No errors
      "sling:adaptTo adaptable='${resource}' adaptTo='com.mypackage.client.core.models.Testmodel' var="model""

      model just returns name of view bundle

      Delete
    4. im my case it is returning null..:(

      Delete
    5. Also i cannot get the properties of the child node...

      Delete