Im constructing a custom component below is its layout.
Header section built using <h1>
Body section which uses out of the box embed component <div data-sly-resource="${'embed' @ resourceType='core/wcm/components/embed/v2/embed'}"></div>
Footer that is again some HTML code
Im using embed component in the HTML mode where, I want to populate it content from a content fragment (that holds all the data in JSON format).
So when user drags and drops the stitched custom component, he will just choose the content fragment from dialog and it sling model will read it and return data for all the fields that the component is displaying using HTL. Now how do I feed data html content into the out of the box embed component either using HTL or sling model.
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
@Model(adaptables = SlingHttpServletRequest.class, adapters = CustomComponentModel.class, resourceType = CustomComponentModel.RESOURCE_TYPE)
public class CustomComponentModel extends WCMUsePojo {
public static final String RESOURCE_TYPE = "your/component/resource/type";
@JsonIgnore
private ContentFragment contentFragment;
@Override
public void activate() throws Exception {
contentFragment = getContentFragment();
}
public ContentFragment getContentFragment() {
return contentFragment;
}
}
private ContentFragment getContentFragment() {
ResourceResolver resourceResolver = getResourceResolver();
ContentFragmentManager contentFragmentManager = resourceResolver.adaptTo(ContentFragmentManager.class);
// Get the content fragment path from the component properties or dialog
String contentFragmentPath = getProperties().get("contentFragmentPath", String.class);
if (StringUtils.isNotBlank(contentFragmentPath)) {
Resource contentFragmentResource = resourceResolver.getResource(contentFragmentPath);
if (contentFragmentResource != null) {
return contentFragmentManager.getContentFragment(contentFragmentResource);
}
}
return null;
}
<div data-sly-use.model="your.package.CustomComponentModel">
<h1>${model.contentFragment.title}</h1>
<div data-sly-resource="${'embed' @ resourceType='core/wcm/components/embed/v2/embed', source=model.contentFragment.embedSource}"></div>
<footer>${model.contentFragment.footer}</footer>
</div>
Hi @Ashwin_KumarSr ,
To populate the out-of-the-box Embed component with data from a content fragment using HTL or a Sling model, you'll need to set the appropriate properties of the Embed component. Here's how you can achieve this:
Using HTL: You can use HTL to dynamically set the properties of the Embed component based on the selected content fragment.
<!-- Your component markup -->
<div data-sly-resource="${'embed' @ resourceType='core/wcm/components/embed/v2/embed',
src=myContentFragmentPath}"></div>
In this example, myContentFragmentPath is a variable representing the path to the selected content fragment. You need to populate this variable in your dialog's Sling model.
Using a Sling Model: You can use a Sling model to retrieve the data from the content fragment and pass it to your HTL markup.
First, create a Sling model that retrieves the necessary data from the content fragment:
import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.wcm.core.components.models.Embed;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import javax.inject.Inject;
@Model(
adaptables = Resource.class,
adapters = { Embed.class, ComponentExporter.class },
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class MyEmbedModel implements Embed {
@Inject
private String src; // Path to your content fragment
@Override
public String getSrc() {
return src;
}
}
Then, in your HTL markup, use the Sling model to set the src property of the Embed component:
<div data-sly-use.embedModel="com.example.models.MyEmbedModel"
data-sly-resource="${'embed' @ resourceType='core/wcm/components/embed/v2/embed',
src=embedModel.src}"></div>
In this example, com.example.models.MyEmbedModel is the fully qualified class name of your Sling model.
By following either of these approaches, you can dynamically set the HTML content of the out-of-the-box Embed component based on the data from the selected content fragment. Ensure that your Sling model retrieves the necessary data from the content fragment and sets the appropriate properties of the Embed component.
Thanks!
Thanks for the detailed explanation.
I tried the approach suggested but couldn't get it working. Here is the code
1) Sling Model
package com.sn.content.exp.core.models;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import com.adobe.cq.wcm.core.components.models.Embed;
@Model(adaptables = SlingHttpServletRequest.class, adapters = Embed.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class KBEmbedImpl implements Embed {
private String src;
public String getSrc() {
return "<h1>From Sling Model</h1>";
}
}
2) HTL
<sly data-sly-use.kb="com.sn.content.exp.core.models.KnowledgeArticle"
data-sly-use.kbembed="com.sn.content.exp.core.models.KBEmbedImpl">
<div class="cmp-kb__body">
<div data-sly-resource="${'embed' @ resourceType='core/wcm/components/embed/v2/embed', src=kbembed.src}"></div>
</div>
</sly>
With above code, the embed component doesn't show on the page the HTML Im passing via sling model, but the value I added through dialog from UI.
How is the src value being passed to embed component via data-sly-resource setting up the html field of the component. I did read about this core component couldn't find anything on src attribute.
@Model(adaptables = SlingHttpServletRequest.class, adapters = CustomComponentModel.class, resourceType = CustomComponentModel.RESOURCE_TYPE)
public class CustomComponentModel extends WCMUsePojo {
public static final String RESOURCE_TYPE = "your/component/resource/type";
@JsonIgnore
private ContentFragment contentFragment;
@Override
public void activate() throws Exception {
contentFragment = getContentFragment();
}
public ContentFragment getContentFragment() {
return contentFragment;
}
}
private ContentFragment getContentFragment() {
ResourceResolver resourceResolver = getResourceResolver();
ContentFragmentManager contentFragmentManager = resourceResolver.adaptTo(ContentFragmentManager.class);
// Get the content fragment path from the component properties or dialog
String contentFragmentPath = getProperties().get("contentFragmentPath", String.class);
if (StringUtils.isNotBlank(contentFragmentPath)) {
Resource contentFragmentResource = resourceResolver.getResource(contentFragmentPath);
if (contentFragmentResource != null) {
return contentFragmentManager.getContentFragment(contentFragmentResource);
}
}
return null;
}
<div data-sly-use.model="your.package.CustomComponentModel">
<h1>${model.contentFragment.title}</h1>
<div data-sly-resource="${'embed' @ resourceType='core/wcm/components/embed/v2/embed', source=model.contentFragment.embedSource}"></div>
<footer>${model.contentFragment.footer}</footer>
</div>
@Ashwin_KumarSr Did you find the suggestion helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.
Views
Replies
Total Likes
Views
Likes
Replies