I am trying to understand Delegation patterns better when we extend the core components Sling model.
I am following the example provided here https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models to extend the Teaser component. Basically, I want all the properties defined in the Teaser component and add a few more.
Whatever new properties I am adding to the custom sling model, I can access those, and they return the correct values. But the properties defined in the core component Teaser model return no value. Upon debugging, I noticed that values are being populated correctly in the private teaser property, so I thought of returning the whole Teaser object through the getter as shown in the below code snippet. (again, not sure if this is a good solution or not).
@Deleted Account
@Via(type = ResourceSuperType.class)
private Teaser teaser;
public Teaser getTeaser() {
return teaser;
}
Now, I can access the core component's properties and read the values, but now my HTL looks ugly because to access the core component's properties, I have to write a teaser before those properties and not directly.
<div data-sly-use.customTeaser="com.company.subdomain.core.models.CustomTeaser">
<h2>${customTeaser.teaser.title}</h2>
</div>
I am sure I am doing something wrong here; that's why I wanted to reach out to the community to get some better ideas. Is there any other approach to extend a core component easily? Is something that needs to be done differently when implementing a delegation pattern to access core components properties without overriding each one?
Solved! Go to Solution.
Views
Replies
Total Likes
Faced a similar issue. Leaving a reply so that it helps others who come across the same problem.
The reason the core component properties are null is that currently, the above delegate sling model doesn't have access to core component properties. You will have to override all the helper methods, not just the ones you are modifying. For example, say you are not changing any logic related to 'title', still you will have to override getTitle().
@Override
public String getTitle() {
return Teaser.getTitle()
}
Or you can use Lombok to get rid of the boilerplate code.
https://blogs.perficient.com/2021/06/14/writing-less-java-code-in-aem-with-sling-models-lombok/
your code looks correct, can you show with us your implementation of the sling model using the delegation pattern?
Also make sure that your top level annotations are correct,
@Model(adaptables = SlingHttpServletRequest.class, adapters = Teaser.class, resourceType = "myproject/components/myTeaser")
Faced a similar issue. Leaving a reply so that it helps others who come across the same problem.
The reason the core component properties are null is that currently, the above delegate sling model doesn't have access to core component properties. You will have to override all the helper methods, not just the ones you are modifying. For example, say you are not changing any logic related to 'title', still you will have to override getTitle().
@Override
public String getTitle() {
return Teaser.getTitle()
}
Or you can use Lombok to get rid of the boilerplate code.
https://blogs.perficient.com/2021/06/14/writing-less-java-code-in-aem-with-sling-models-lombok/
For any body who is trying to use the delegation pattern , the mistake you might be doing is with the Service you are importing in your HTL. For example if you are doing this approach
https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models
In your HTL , do not import your custom model, but always use `
data-sly-use.title="com.adobe.cq.wcm.core.components.models.Title
the core components Model
If you use your Model , then as @JeevanRaj was mentioning , you will have to ovveride every method in the Core Model Interface.
So in your case instead of using
data-sly-use.customTeaser="com.company.subdomain.core.models.CustomTeaser"
, if you use
data-sly-use.teaser="com.adobe.cq.wcm.core.components.models.Teaser"
It will work, because you have written the Model to run when the resource Type is
resourceType = "myproject/components/myTeaser"
In case the core component model is used in the HTL, we will have to override all the methods(or use Lombok).
data-sly-use.title="com.adobe.cq.wcm.core.components.models.Title
Never tried using the custom model in HTL for Sling delegation.
I am working with core components right now and I am also using the delegation pattern. But I didn't face the issue which you are mentioning @JeevanRaj .
@JeevanRaj I got why you have to ovveride all the methods.
https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models In this if you add `@delegate` along with below
@Delegate @Self @Via(type = ResourceSuperType.class) private Title title;
then you need not ovveride any methods
But if you have to rewrite the logic of any of the existing methods, you should not use @Delegate and ovverride all the methods.
Thanks
Veena ✌
Views
Likes
Replies