Hello @mukeshaem -
The extra new lines in the RTE field's list items are a default behavior in AEM's content fragment JSON representation. It includes new line characters ("\n") for better readability and formatting purposes.
If you want to remove these extra new lines from the JSON content, you can customize the serialization process of the content fragment model. Here's an example of how you can achieve this:
1. Create a new Java class that extends the WCMUsePojo class:
package com.example.core.models;
import org.apache.sling.api.resource.Resource;
import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData;
import com.adobe.cq.wcm.core.components.models.datalayer.ComponentDataUtil;
import com.adobe.cq.wcm.core.components.models.datalayer.ExporterDataImpl;
import com.adobe.cq.wcm.core.components.models.datalayer.builder.DataLayerBuilder;
import com.adobe.cq.wcm.core.components.models.datalayer.builder.DataLayerBuilderFactory;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.EditConfig;
import com.day.cq.wcm.api.components.EditContext;
import com.day.cq.wcm.api.components.InplaceEditingConfig;
import com.day.cq.wcm.api.components.InplaceEditingConfig.Type;
import com.day.cq.wcm.api.components.RefreshMode;
import com.day.cq.wcm.api.designer.Style;
import com.day.cq.wcm.api.policies.ContentPolicy;
import com.day.cq.wcm.api.policies.ContentPolicyMapping;
import com.day.cq.wcm.api.policies.ContentPolicyManager;
import com.day.cq.wcm.commons.WCMUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CustomContentFragmentModel extends WCMUsePojo implements ComponentExporter {
private static final String COMPONENT_DATA_NAME = "componentData";
private static final String COMPONENT_RESOURCE_TYPE = "my-project/components/content/contentfragment";
private static final String SLING_MODEL_CLASS = "com.example.core.models.CustomContentFragmentModel";
private String jsonString;
private JsonNode componentData;
private ComponentData data;
private String resourceType;
@Override
public void activate() throws Exception {
HttpServletRequest request = getRequest();
Resource resource = getResource();
Style currentStyle = WCMUtils.getStyle(request);
// Get the content policy mapping for the resource
ContentPolicyManager policyManager = resource.getResourceResolver().adaptTo(ContentPolicyManager.class);
ContentPolicyMapping policyMapping = policyManager.getPolicyMapping(resource);
if (policyMapping != null) {
ContentPolicy contentPolicy = policyMapping.getPolicy();
currentStyle = contentPolicy.getStyle(resource);
}
// Get the component resource type
Component component = resource.adaptTo(Component.class);
if (component != null) {
resourceType = component.getResourceType();
}
// Build the data layer for the component
DataLayerBuilder dataLayerBuilder = DataLayerBuilderFactory.create(resource, currentStyle, request,
componentDataUtil, COMPONENT_RESOURCE_TYPE, SLING_MODEL_CLASS);
data = dataLayerBuilder.build();
// Serialize the component data to JSON
ObjectMapper objectMapper = new ObjectMapper();
StringWriter stringWriter = new StringWriter();
objectMapper.writeValue(stringWriter, data);
jsonString = stringWriter.toString();
// Parse the JSON string to retrieve the component data
componentData = objectMapper.readTree(jsonString);
}
public String getJsonString() {
return jsonString;
}
public JsonNode getComponentData() {
return componentData;
}
@Override
public String getExportedType() {
return COMPONENT_RESOURCE_TYPE;
}
}
2. Update your Sling Model class to use this new class as a property:
mpackage com.example.core.models;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.ExporterOption;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.Self;
import com.adobe.cq.export.json.ExporterConstants;
import com.day.cq.wcm.api.Page;
import javax.inject.Inject;
@Model(
adaptables = Resource.class,
adapters = { CustomContentFragmentModel.class },
resourceType = "my-project/components/content/contentfragment",
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
@Exporter(
name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
extensions = ExporterConstants.SLING_MODEL_EXTENSION,
options = {
@ExporterOption(name = ExporterConstants.OPTION_SERIALIZE_PRETTY, value = "true")
}
)
public class CustomContentFragmentModel {
@Self(injectionStrategy = InjectionStrategy.OPTIONAL)
private Resource resource;
@Inject
private Page currentPage;
@Inject
private String title;
// ... other properties and methods
}
3. Update your Sightly file to use the updated Sling Model:
<sly data-sly-use.customContentFragmentModel="com.example.core.models.CustomContentFragmentModel"
data-sly-use.customContentFragmentModelJson="com.fasterxml.jackson.databind.ObjectMapper">
<!-- Render the modified JSON without extra new lines -->
${customContentFragmentModelJson.writeValueAsString(customContentFragmentModel.componentData)}
</sly>
Now with this implementation, you can retrieve the JSON data for the content fragment model and then serialize it using the ObjectMapper without the extra new lines.