What is the equivalent of this code if using Sling Model | Community
Skip to main content
jydps87387977
Level 3
March 10, 2016
Solved

What is the equivalent of this code if using Sling Model

  • March 10, 2016
  • 8 replies
  • 6580 views

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

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by smacdonald2008

"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.  

8 replies

edubey
Level 10
March 10, 2016
@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.

smacdonald2008
Level 10
March 10, 2016

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. 

jydps87387977
Level 3
March 10, 2016

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)

smacdonald2008
Level 10
March 10, 2016

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

Level 3
March 10, 2016

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

jydps87387977
Level 3
March 10, 2016

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' ?

smacdonald2008
smacdonald2008Accepted solution
Level 10
March 10, 2016

"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.  

Level 3
March 14, 2016

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