Tuesday 31 January 2023

Fetch Content Fragment using Sling Model

We have seen how to create a content fragment in the previous post.

Content Fragments can be rendered onto a page by below different ways:
  1. Using AEM core components
  2. Using Custom Sling Model
  3. Using Servlet to access Content Fragment.


Let's see how to render Content Fragment using the sling Model.

Create an AEM component "samplecontentfragment" which calls the sling model SampleContentFragment.java

samplecontentfragment.html

<p data-sly-test="${properties.text}">Text property: ${properties.text}</p>


Render Content Fragment using Sling Model 
Title: ${model.title}
Description: ${model.description}
Release Date: ${model.releaseDate}
</img>
</sly>

SampleContentFragment.java

package com.adobe.aemquickstart.core.models;

import java.util.Calendar;
import java.util.Optional;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;

import com.adobe.cq.dam.cfm.ContentElement;
import com.adobe.cq.dam.cfm.ContentFragment;
import com.adobe.cq.dam.cfm.FragmentData;
import com.adobe.cq.dam.cfm.FragmentTemplate;

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class SampleContentFragment {
 public static final String MODEL_TITLE = "AEM Book";
 public static final String CF_PATH = "/content/dam/aemquickstart/content-fragments/aem-book";

 @Inject
 @Self
 private Resource resource;
 @Inject
 ResourceResolver resourceResolver;
 private Optional<ContentFragment> contentFragment;

 @PostConstruct
 public void init() {
  Resource fragmentResource = resourceResolver.getResource(CF_PATH);
  contentFragment = Optional.ofNullable(fragmentResource.adaptTo(ContentFragment.class));
 }

 public String getTitle() {
  return contentFragment.map(cf -> cf.getElement("title")).map(ContentElement::getContent)
    .orElse(StringUtils.EMPTY);
 }

 public String getDescription() {
  return contentFragment.map(cf -> cf.getElement("description")).map(ContentElement::getContent)
    .orElse(StringUtils.EMPTY);
 }

 public Calendar getReleaseDate() {
  return ((Calendar) contentFragment.map(cf -> cf.getElement("releaseDate")).map(ContentElement::getValue)
    .map(FragmentData::getValue).orElse(StringUtils.EMPTY));
 }

 public String getImage() {
  return contentFragment.map(cf -> cf.getElement("image")).map(ContentElement::getContent)
    .orElse(StringUtils.EMPTY);
 }
}

Add the new component on to the page and refresh the page.


3 comments :

  1. If you only care about the master variation and none of the metadata, you can also make a model bean for that one specific child node (jcr:content/data/master)

    ReplyDelete
  2. How to get values if it has ariations

    ReplyDelete
  3. Hot to get values using sling model if content fragment has variations

    ReplyDelete