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
Views
Likes
Replies