HTL is ignoring the passed resource as param to Sling Model | Community
Skip to main content
NageshRaja
Level 5
April 6, 2026
Solved

HTL is ignoring the passed resource as param to Sling Model

  • April 6, 2026
  • 3 replies
  • 54 views

Hi All,

I am trying to render an image from a multifield item using a Sling Model - 

If I print the below in sightly here’s the result for it - 

<p>RESOURCE is ${tableList}</p>

RESOURCE is /content/projectA/en/home/jcr:content/root/responsivegrid_1161940076/banner_1463578421/customMultifield/item0

I try to pass this resource to a custom sling model like below - 

<sly data-sly-use.slimItem="${'org.projA.web.core.models.customModel' @ resource=tableList}"></sly>

When I do the above and try to log it in the init function of sling model customModel, I get the below - 

@PostConstructprotected void init() {    LOG.error("RESOURCE PATH: {}", resource.getPath());}I get the following in the error log - 

06.04.2026 23:22:43.593 *ERROR* [[0:0:0:0:0:0:0:1] [1775497963265] GET /content/projectA/en/home.html HTTP/1.1] org.projA.ctcweb.web.models.customModel RESOURCE PATH: /projectA/en/home/jcr:content/root/responsivegrid_1161940076/banner_1463578421

 

Question - Why is the /customMultifield/item0 not being passed to the sling model?

 

Thanks,

NK

Best answer by giuseppebaglio

hi ​@PGURUKRISHNA,

The resourceResolver.resolve() method resolves to the nearest resource that Sling can match with a sling:resourceType. The customMultifield/item0 node is typically an nt:unstructured child without its own resource type, so Sling's resolution bubbles up to the nearest typed ancestor — banner_1463578421 — dropping /customMultifield/item0 entirely.

The correct parameter to pass a child resource as the adaptable is adaptable, not resource:

<sly data-sly-use.slimItem="${'org.projA.web.core.models.customModel' @ adaptable=tableList}"></sly>

This passes the Resource object directly to adaptTo(), bypassing the resolve() path entirely. Your Sling Model must declare Resource.class as an adaptable.
If you need to keep the model adapted from SlingHttpServletRequest, pass the path as a named String and resolve it explicitly inside the model using getResource():

<sly data-sly-use.slimItem="${'org.projA.web.core.models.customModel' @ itemPath=tableList.path}"></sly>

The cleanest pattern for multifields is to handle the iteration entirely in a parent Sling Model using @ChildResource, rather than instantiating per-item models from HTL:

@ChildResource
private List<Resource> customMultifield; // injects all item0, item1... automatically
 

3 replies

Lokesh_Vajrala
Community Advisor
Community Advisor
April 7, 2026

Hi ​@NageshRaja 

I think the issue is that while the multifield item path is being passed, your Sling Model may not be explicitly consuming that resource. Because of that, it’s likely defaulting to the current component resource (the banner component) instead of /customMultifield/item0.

You can try ensuring the Sling Model explicitly accepts the passed resource. For example, check if your model is adaptable from Resource. If not, you could use @Via("resource") to inject the passed resource.

Thanks,

Lokesh

giuseppebaglio
giuseppebaglioAccepted solution
Level 10
April 7, 2026

hi ​@PGURUKRISHNA,

The resourceResolver.resolve() method resolves to the nearest resource that Sling can match with a sling:resourceType. The customMultifield/item0 node is typically an nt:unstructured child without its own resource type, so Sling's resolution bubbles up to the nearest typed ancestor — banner_1463578421 — dropping /customMultifield/item0 entirely.

The correct parameter to pass a child resource as the adaptable is adaptable, not resource:

<sly data-sly-use.slimItem="${'org.projA.web.core.models.customModel' @ adaptable=tableList}"></sly>

This passes the Resource object directly to adaptTo(), bypassing the resolve() path entirely. Your Sling Model must declare Resource.class as an adaptable.
If you need to keep the model adapted from SlingHttpServletRequest, pass the path as a named String and resolve it explicitly inside the model using getResource():

<sly data-sly-use.slimItem="${'org.projA.web.core.models.customModel' @ itemPath=tableList.path}"></sly>

The cleanest pattern for multifields is to handle the iteration entirely in a parent Sling Model using @ChildResource, rather than instantiating per-item models from HTL:

@ChildResource
private List<Resource> customMultifield; // injects all item0, item1... automatically
 
VeenaVikraman
Community Advisor
Community Advisor
April 8, 2026

Hi ​@NageshRaja 

 

@giuseppebaglio  has covered this really well. Just to add one practical point from what I have seen across projects , the `@ChildResource`pattern he mentions at the end is by far the cleanest approach for multifields and is what I would recommend as the default pattern when dealing with multifield items in Sling Models.

 

Instantiating a per-item model from HTL using `data-sly-use` inside a loop can get tricky, especially when the child nodes are nt:unstructured without their own resource type, which is exactly the behaviour you ran into here. Handling the iteration inside a parent Sling Model using `@ChildResource` keeps your HTL clean and avoids this resolution issue entirely.

 

Hope this helps!

Thanks

Veena