Hi
I’m trying to use a simple Sling Model from HTL, but the model never instantiates (null bindings). I suspect I’m missing something obvious with the adaptable.
Sling Model
package com.acme.core.models;
import javax.inject.Inject;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
@Model(
adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class TeaserModel {
@inject
private String title;
public String getTitle() {
return title;
}
}
Sightly
<div data-sly-use.m="com.acme.core.models.TeaserModel">
<h2>${m.title}</h2>
</div>
When I check the logs here is what I get, what wrong here?
org.apache.sling.models.impl.ModelAdapterFactory Could not adapt
org.apache.sling.api.SlingHttpServletRequest to com.acme.core.models.TeaserModel
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @AnujaRa,
I think, HTL tries to adapt from the request by default, but your model is Resource-adaptable.
You have 2 options:
1. Make the model request-adaptable (HTL unchanged):
@Model(
adaptables = org.apache.sling.api.SlingHttpServletRequest.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class TeaserModel {
@org.apache.sling.models.annotations.injectorspecific.ValueMapValue(
name = org.apache.jackrabbit.JcrConstants.JCR_TITLE
)
private String title;
public String getTitle() { return title; }
}
2. Keep Resource-adaptable and force resource adaptation in HTL:
<div data-sly-use.m="${'com.acme.core.models.TeaserModel' @ resource=resource}">
<h2>${m.title}</h2>
</div>
Also, I see property name mismatch in your code: Field is title, but the JCR property is jcr:title. With plain @Inject it won’t map.
Try to use @ValueMapValue(name = "jcr:title") (shown above) or rename the field to jcr:title (not recommended).
Your model says it adapts from Resource.class, but HTL uses the SlingHttpServletRequest as the adaptable by default when using data-sly-use. Because the model isn’t configured to adapt from request, adaptation fails and returns null.
Change your model to adapt from SlingHttpServletRequest.class
@Model(adaptables = SlingHttpServletRequest.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TeaserModel {
@inject
private String title;
public String getTitle() {
return title;
}
}
This way, when HTL runs data-sly-use, it adapts the current request to your model, which matches the adaptable.
Hi @AnujaRa,
I think, HTL tries to adapt from the request by default, but your model is Resource-adaptable.
You have 2 options:
1. Make the model request-adaptable (HTL unchanged):
@Model(
adaptables = org.apache.sling.api.SlingHttpServletRequest.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class TeaserModel {
@org.apache.sling.models.annotations.injectorspecific.ValueMapValue(
name = org.apache.jackrabbit.JcrConstants.JCR_TITLE
)
private String title;
public String getTitle() { return title; }
}
2. Keep Resource-adaptable and force resource adaptation in HTL:
<div data-sly-use.m="${'com.acme.core.models.TeaserModel' @ resource=resource}">
<h2>${m.title}</h2>
</div>
Also, I see property name mismatch in your code: Field is title, but the JCR property is jcr:title. With plain @Inject it won’t map.
Try to use @ValueMapValue(name = "jcr:title") (shown above) or rename the field to jcr:title (not recommended).
@SantoshSai Thanks for the last point you mentioned about mapping title field, inititally I tried SlingHttpServletRequest but may be because of field mismatch it didn't worked but now it worked!
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies