Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
SOLVED

What is the equivalent of this code if using Sling Model

Avatar

Level 4

Code Snippet

        final Resource jcrResource = resource.getChild("jcr:content");
        final ValueMap valueMap = jcrResource.adaptTo(ValueMap.class);
        final String title = valueMap.get("jcr:title", ""); // GETTING THE TITLE POPULATED WITH SOME VALUE

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Here is what I tried, but it does not work:

@ValueMapValue(name = "jcr:title", optional = true)
    private String title; // TITLE IS NOT GETTING POPULATED

1 Accepted Solution

Avatar

Correct answer by
Level 10

"Is any way to use adaptTo() for the resource '/content/geometrixx-outdoors' ?"

If you are using a Node T (a resource) with props A B C - then you can map to properties A B C in the Sling Model class. For example: 

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
 
@Model(adaptables = Resource.class)
public class ResourceInfo {
    @Inject
    private String A;
    @Inject
    private String B;
    @Inject
    private String C;
     
   public String getA() {
        return A;
    }
    public String getB() {
        return B;
    }
    public String getC() {
        return C;
    }
 
}

So in your example- you say this path: 

/content/geometrixx-outdoors

Well this node does not have many props to map to. See: 

Because there is few props on this node - it does not make sense to map to these in a Sling Model. 

If you use this node: /content/geometrixx-outdoors/jcr:content - you can map to these properties: 

I hope this helps clear up Sling Models and the relationship between nodes and properties with Sling Models.  

View solution in original post

8 Replies

Avatar

Level 10
@Model(adaptables=Resource.class) public class MyModel { @Inject @Named("jcr:title") private String title; }

This should work

Adapt as resource and inject the property you need.

Avatar

Level 10

Also - to add to what Praveen has stated -- take a look at this AEM community article. It will show you this pattern in an AEM Example: 

https://helpx.adobe.com/experience-manager/using/sling_models.html

Hope this helps. 

Avatar

Level 4

The code above didn't work:

"org.apache.sling.models.impl.ModelAdapterFactory Required properties [private java.lang.String model.Page.title] on model class class model.Page were not able to be injected."

 

Just bear in mind that, I am trying to access resource.getChild("jcr:content"), and then adaptTo (ValueMap)

Avatar

Level 10

In Sling modeling - 

A Sling Model is implemented as an OSGi bundle. A Java class located in the OSGi bundle is annotated with@Model and the adaptable class (for example, @Model(adaptables = Resource.class). The data members (Fields) use @Inject annotations. These data members map to node properties.

So you are mapping to node props - not child node props. 

https://sling.apache.org/documentation/bundles/models.html#basic-usage

Avatar

Level 3

Hi 
The possible reasons for not working 
1. Please check in your felix console system/console/adapters whether your adapter is available or not. If it is not available you have to make sure to add the <sling-models>package.name</sling-models> this to your maven bundle plugin so that your sling models package will be added to the manifest.mf file. This is important because OSGi container will understand read this from manifest file and exposes your adaptable classes.
2. As you are using Injector-specific Annotations Make sure that you have a sling models impl 1.0.6 in your AEM instance


The simplest way to inject properties is by using @inject annotation. Refer to this article for more information on adapting resource object to custom class
resource.adaptTo(CustomClass.class)
https://helpx.adobe.com/experience-manager/using/sling_models.html

Avatar

Level 4

Here are my finding from the testing:

@Inject @Named("jcr:title")private String title;

It works with the path /content/geometrixx-outdoors/jcr:content

It does NOT work with the path : /content/geometrixx-outdoors

 

My initial question was if there is any way to use adaptTo() for the resource '/content/geometrixx-outdoors' ?

Avatar

Correct answer by
Level 10

"Is any way to use adaptTo() for the resource '/content/geometrixx-outdoors' ?"

If you are using a Node T (a resource) with props A B C - then you can map to properties A B C in the Sling Model class. For example: 

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
 
@Model(adaptables = Resource.class)
public class ResourceInfo {
    @Inject
    private String A;
    @Inject
    private String B;
    @Inject
    private String C;
     
   public String getA() {
        return A;
    }
    public String getB() {
        return B;
    }
    public String getC() {
        return C;
    }
 
}

So in your example- you say this path: 

/content/geometrixx-outdoors

Well this node does not have many props to map to. See: 

Because there is few props on this node - it does not make sense to map to these in a Sling Model. 

If you use this node: /content/geometrixx-outdoors/jcr:content - you can map to these properties: 

I hope this helps clear up Sling Models and the relationship between nodes and properties with Sling Models.  

Avatar

Level 3

You can adaptTo() /content/geometrixx-outdoors'  but you have to change @Named("jcr:title") to some property which is there at that particular node for example jcr:created or jcr:createdBy or jcr:primaryType. Because there is no property called jsc:title at /content/geometrixx-outdoors if u try to adapt it will give null.

Thanks,

kalyan