Expand my Community achievements bar.

SOLVED

Sling Models: Using @Source("child-resources")

Avatar

Level 2

I have not been able to get the "child-resources" injector to work within the @Source annotation.

Documentation I am using: http://sling.apache.org/documentation/bundles/models.html

I have tried to use the @Inject with a List<Resources> object. Does anyone have an example of this injector working? The ACS Commons does not have an example of this. My model works when I remove the children code and only get the title.

package com.github.models.models; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Source; @Model(adaptables=Resource.class) public class Region { @Inject @Named("jcr:title") private String title; @Inject @Source("child-resources") private List<Resource> children; public String getTitle() { return title; } public List<Resource> getChildren() { return children; } }
1 Accepted Solution

Avatar

Correct answer by
Employee

There are a significant number of example model classes in the Sling Models test suite. That is always a good point of reference.

In your example (assuming you are using Sling Models Impl 1.0.6 or higher), what this will attempt to inject are the children of the child resource named children, i.e. the *grand* children of the adaptable resource. Or, in the words of the documentation:

"List injection for child resources works by injecting grand child resources (since Sling Models Impl 1.0.6)."

At present, there is no way to inject the direct children of the adaptable. The reason originally was that this was trivial to do:

@Model(adaptables=Resource.class) public class Region { @Inject private Resource resource; public Iterable<Resource> getChildren() { return resource.getChildren();     } }

I'm open to adding support for injection of the direct child nodes. The problem, however, is that we would have to establish a special name to indicate that this should happen. Something like this:

@Inject @Named(".") private List<Resource> children;

My fear is that this is less intuitive than the current behavior.

Justin

View solution in original post

4 Replies

Avatar

Correct answer by
Employee

There are a significant number of example model classes in the Sling Models test suite. That is always a good point of reference.

In your example (assuming you are using Sling Models Impl 1.0.6 or higher), what this will attempt to inject are the children of the child resource named children, i.e. the *grand* children of the adaptable resource. Or, in the words of the documentation:

"List injection for child resources works by injecting grand child resources (since Sling Models Impl 1.0.6)."

At present, there is no way to inject the direct children of the adaptable. The reason originally was that this was trivial to do:

@Model(adaptables=Resource.class) public class Region { @Inject private Resource resource; public Iterable<Resource> getChildren() { return resource.getChildren();     } }

I'm open to adding support for injection of the direct child nodes. The problem, however, is that we would have to establish a special name to indicate that this should happen. Something like this:

@Inject @Named(".") private List<Resource> children;

My fear is that this is less intuitive than the current behavior.

Justin

Avatar

Level 9

There are examples for @Inject in wcm.io Libraries and extensions for AEM applications

you can download the whole project from github https://github.com/wcm-io/wcm-io

There is a ppt on slideshare http://www.slideshare.net/justinedelson/sling-models-overview

Please try it out

Avatar

Level 2

Thank-you, Justin. That makes a great deal of sense. I was too focused at first and trying to do it all through injection. It is not cheating to use what is already there, is it?

I was able to get injection of grandchildren to work and that works well.

Avatar

Employee

Xavier Dupertious wrote...

Thank-you, Justin. That makes a great deal of sense. I was too focused at first and trying to do it all through injection. It is not cheating to use what is already there, is it?

I was able to get injection of grandchildren to work and that works well.

 

Ha! No, it isn't cheating at all. I guess I don't have enough confidence in the @Named(".") syntax. Maybe:

@Inject @MyChildren private List<Resource> children

;)