Hi all,
I'm enhancing the image component by adding 2 extra fields Tablet image and Mobile image
I have extended the Image sling models with my CustomImage interface but its not rendering the existing image functionality and my enhancement as well I'm not sure what is missing please help me on the same.
Have added Impl, Interface and HTL.
Interface:
Thanks and Regards
Hari Prasath V
@arunk @arunpatidar @SantoshSai @LokeshVajrala @Saravanan_Dharmaraj @krati_garg
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @HariDo ,
I would use Delegation Pattern for Sling Models[0] where logic can be extended by using a Sling delegation pattern. "The Business logic for the core-components is implemented in Sling Models. In case it is necessary to customize the business logic to fulfill project specific requirements the delegation Pattern for Sling Models can be used"
Please refer[1],[2] similar example has been given for Image component.
import com.adobe.cq.wcm.core.components.models.Image;
import lombok.experimental.Delegate;
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.Via;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.annotations.via.ResourceSuperType;
@Model(
adaptables = {Resource.class, SlingHttpServletRequest.class},
adapters = Image.class, // Adapts to the CC model interface
resourceType = "demo/components/content/image", // Maps to OUR component, not the CC component
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL // No properties? No problem!
)
public class CustomImage implements Image { // We will be honoring the contract between the HTL and the model implementation
@Self // Indicates that we are resolving the current resource
@Via(type = ResourceSuperType.class) // Resolve not as this model, but as the model of our supertype (ie: CC Image)
@Delegate(excludes = DelegationExclusion.class) // Delegate all our methods to the CC Image except those defined below
private Image delegate;
@ValueMapValue
private boolean useOriginal; // This is a new property that we are introducing
@ValueMapValue
protected String fileReference; // This is the CC Image property that point to the image asset location in the DAM
@Override
public String getSrc() {
// If useOriginal is checked, then serve the raw asset in full resolution, otherwise,
// delegate this method to the CC Image
return useOriginal ? fileReference : delegate.getSrc();
}
private interface DelegationExclusion { // Here we define the methods we want to override
String getSrc(); // Override the method which determines the source of the asset
}
}
[0]: https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models
[1]: https://kiransg.com/2021/11/07/aem-core-component-delegation/
Hope thats helps!
Regards,
Santosh
Hi @HariDo ,
I would use Delegation Pattern for Sling Models[0] where logic can be extended by using a Sling delegation pattern. "The Business logic for the core-components is implemented in Sling Models. In case it is necessary to customize the business logic to fulfill project specific requirements the delegation Pattern for Sling Models can be used"
Please refer[1],[2] similar example has been given for Image component.
import com.adobe.cq.wcm.core.components.models.Image;
import lombok.experimental.Delegate;
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.Via;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.annotations.via.ResourceSuperType;
@Model(
adaptables = {Resource.class, SlingHttpServletRequest.class},
adapters = Image.class, // Adapts to the CC model interface
resourceType = "demo/components/content/image", // Maps to OUR component, not the CC component
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL // No properties? No problem!
)
public class CustomImage implements Image { // We will be honoring the contract between the HTL and the model implementation
@Self // Indicates that we are resolving the current resource
@Via(type = ResourceSuperType.class) // Resolve not as this model, but as the model of our supertype (ie: CC Image)
@Delegate(excludes = DelegationExclusion.class) // Delegate all our methods to the CC Image except those defined below
private Image delegate;
@ValueMapValue
private boolean useOriginal; // This is a new property that we are introducing
@ValueMapValue
protected String fileReference; // This is the CC Image property that point to the image asset location in the DAM
@Override
public String getSrc() {
// If useOriginal is checked, then serve the raw asset in full resolution, otherwise,
// delegate this method to the CC Image
return useOriginal ? fileReference : delegate.getSrc();
}
private interface DelegationExclusion { // Here we define the methods we want to override
String getSrc(); // Override the method which determines the source of the asset
}
}
[0]: https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models
[1]: https://kiransg.com/2021/11/07/aem-core-component-delegation/
Hope thats helps!
Regards,
Santosh
Hi @SantoshSai
yes this helps but I'm not overriding I'm adding 3 new method's(fields) what should i do now i want the core component method's and my 3 new method's as well.
Please help me on this.
Regards
Hari Prasath
@HariDo - That's possible and mentioned in above link - "Delegate OOTB image component and add custom logic on existing methods like getWidth(), getHeight() and getSrcSet() and also add new method getCredit() and getSizes()."
Even if you are adding new methods you have to delegate(it's not overriding) it. Please go through above link to achieve your requirement.
Hi @SantoshSai
I have modified and added a new method but its not rendering the values.
please correct me if i made any mistakes
CustomImage.java
Regards
Hari Do
.
public String getTabletImage() { return "sampleTestForTableImage" }
Can you try this and see if it is rendering in html
@SantoshSai
It is not rendering the String "sampleTestForTableImage" so im making some mistake in my Models could you please sort it out.
package com.myproject.aem.myproject.division.core.components.models; import com.adobe.cq.wcm.core.components.models.Image; import lombok.experimental.Delegate; 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.Via; import org.apache.sling.models.annotations.injectorspecific.Self; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import org.apache.sling.models.annotations.via.ResourceSuperType; @Model(adaptables = { Resource.class, SlingHttpServletRequest.class }, adapters = Image.class, resourceType = CustomImage.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class CustomImage implements Image { protected static final String RESOURCE_TYPE ="myproject/myproject/components/content/image"; @Self @Via(type = ResourceSuperType.class) @Delegate(excludes = DelegationExclusion.class) private Image image; @ValueMapValue private String mobileImage; // Added this new property @ValueMapValue private String tabletImage; // Added this new property @ValueMapValue private String isInline; // Added this new property public String getTabletImage() { return "sampleTestForTableImage"; } public String getIsInline() { return isInline; } public String getMobileImage() { return mobileImage; } private interface DelegationExclusion { } }
@SantoshSai
This worked there was an error in my bundle that's why its not working previously the code is correct and thanks for suggesting this Delegation Method.
Regards
Hari Do