Sling models adapt to great grand child nodes | Community
Skip to main content
Kamal_Kishor
Community Advisor
Community Advisor
March 4, 2024
Solved

Sling models adapt to great grand child nodes

  • March 4, 2024
  • 4 replies
  • 1528 views

Is it possible to adapt to great grand children using sling models. My content structure is as below which is created using nested multi-field.

comp-node/ multi-field-node/ item0/ sub-multi-field-node/ sub-item0/ sub-item1/ item1/ item2/

As I understand with @ChildResource we can adapt grand-child of current resource.
I am looking for a way using annotations to adapt to great grand child nodes i.e sub-item0, sub-item1,..
thank you.

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 Imran Khan

@kamal_kishor create one main component based and two bean sling models. Call first bean sling model using @childResource from main component model and similarly second bean model using @childresource from first bean model.

 

 

import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.ChildResource; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import javax.inject.Named; import java.util.List; @Model( adaptables = {Resource.class, SlingHttpServletRequest.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class CustomImpl { @Named("multi-field-node") @ChildResource public List<Child> child; public List<Child> getChild() { return child; } @Model(adaptables = { SlingHttpServletRequest.class, Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class Child { @Named("sub-multi-field-node") @ChildResource public List<GrandChild> grandChild; public List<GrandChild> getGrandChild() { return grandChild; } } @Model(adaptables = { SlingHttpServletRequest.class, Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class GrandChild { @ValueMapValue public String grandChildField; public String getGrandChildField() { return grandChildField; } } }

 

4 replies

Imran Khan
Community Advisor
Imran KhanCommunity AdvisorAccepted solution
Community Advisor
March 4, 2024

@kamal_kishor create one main component based and two bean sling models. Call first bean sling model using @childResource from main component model and similarly second bean model using @childresource from first bean model.

 

 

import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.ChildResource; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import javax.inject.Named; import java.util.List; @Model( adaptables = {Resource.class, SlingHttpServletRequest.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class CustomImpl { @Named("multi-field-node") @ChildResource public List<Child> child; public List<Child> getChild() { return child; } @Model(adaptables = { SlingHttpServletRequest.class, Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class Child { @Named("sub-multi-field-node") @ChildResource public List<GrandChild> grandChild; public List<GrandChild> getGrandChild() { return grandChild; } } @Model(adaptables = { SlingHttpServletRequest.class, Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class GrandChild { @ValueMapValue public String grandChildField; public String getGrandChildField() { return grandChildField; } } }

 

Kamal_Kishor
Community Advisor
Community Advisor
March 5, 2024

thanks @imran__khan 
I was checking if there was a direct annotation to do so but it seems it isn;t.

SureshDhulipudi
Community Advisor
Community Advisor
March 4, 2024

Can you try like this - Write a Sling Model At each parent level
-- For Node - comp-node and child resource node - multi-field-node
@Model(adaptables = Resource.class)
public class CompNodeModel {

@ChildResource
private MultiFieldNodeModel multiFieldNode;
//-- 
--//
}

 

----

@Model(adaptables = Resource.class)
public class MultiFieldNodeModel {

@586265
private List<ItemModel> items;
/*
*/
}

----

@Model(adaptables = Resource.class)
public class ItemModel {

@ChildResource
private SubMultiFieldNodeModel subMultiFieldNode;
/*
*/
}

 

 

====

 

CompNodeModel compNodeModel = resource.adaptTo(CompNodeModel.class);
List<SubItemModel> subItems = compNodeModel.getMultiFieldNode().getItems().get(0).getSubMultiFieldNode().getSubItems();

arunpatidar
Community Advisor
Community Advisor
March 5, 2024

Hi @kamal_kishor 
There is no grandchildren annotation, if there is one, it would be very expensive in terms of performance to retrive a grand children node from many nodes.

 

You can go ahead with the suggestion by @imran__khan  and @sureshdhulipudi 

 

however you can create your own annotations also.

Arun Patidar
kautuk_sahni
Community Manager
Community Manager
March 7, 2024

@kamal_kishor Did you find the suggestion helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.

Kautuk Sahni