Fetch Multifield Values using Sling Model
Published
Viewed246 times
In accordance with specific project requirements, there might be a need to incorporate Multifield within the component dialog. Let's explore how to retrieve Multifield data and effectively utilize it in HTL.
Here is a sample cq_dialog allowing AEM authors to enter multiple article items.
article / _cq_dialog / .content.xml
<relatedArticles jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
fieldLabel="Related Articles"
composite="{Boolean}true"
required="{Boolean}true">
<field jcr:primaryType="nt:unstructured"
sling:resourceType = "granite/ui/components/coral/foundation/container"
name="./relatedArticles">
<items jcr:primaryType="nt:unstructured">
<articleTitle jcr:primaryType="nt:unstructured"
sling:resourceType = "granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Article Title"
name="./title"/>
<articleDetailsPage jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/coral/common/form/pagefield"
fieldLabel="Article Details Page"
name="./detailsPage"
rootPath="/content/aem-demo"/>
</items>
</field>
</relatedArticles>
For demonstration purposes, we've included an option for the article title. However, you can also fetch the title directly from the page itself, depending on your project requirements.
After authoring the component dialog, multifield data is stored in the content repository as shown below.
content / aem-demo / home
<article jcr:primaryType="nt:unstructured"
sling:resourceType="aem-demo/components/article"
title="Adobe AEM Community Advisor"
author="Mahedi Sabuj">
<relatedArticles jcr:primaryType="nt:unstructured">
<item0 jcr:primaryType="nt:unstructured"
title="Experience League Community"
detailsPage="/content/aem-demo/us/en/aem/community"/>
</relatedArticles>
</article>
To retrieve this data, Sling Model can be utilized. Using
@ChildResource
annotation injectors, we can adapt them to the target type (e.g., ArticleItem
) and populate them with all child resources of the resource identified by the specified name.components / model / Article.java
public class Article {
protected static final String RESOURCE_TYPE = "aem-demo/components/article";
String title;
String author;
List<ArticleItem> relatedArticles;
}
components / model / ArticleItem.java
public class ArticleItem {
String title;
String detailsPage;
}
To showcase related articles in the component's HTML, you can iterate through the list of articles using
data-sly-list
and display their information accordingly.article / article.html
<div data-sly-use.article="com.aem.demo.core.components.models.Article"
data-sly-use.templates="core/wcm/components/commons/v1/templates.html"
data-sly-test.hasContent="${article.title}"
class="article__inner">
<div data-sly-list.item="${article.relatedArticles}">
<a href="${item.detailsPage @ context = 'uri'}">
${item.title}
</a>
</div>
</div>
<sly data-sly-call="${templates.placeholder @
isEmpty = !hasContent, classAppend = 'cmp-article'}"/>
You can externalize the
detailsPage
value according to your business requirements.