I’m trying to export a page with the default model exporter of AEM. This page contains multiple components and some of them have multifields. When I visit homepage.model.json the JSON doesn’t have the multifields.
carousel: {
:type: "mysite/components/public/carousel",
title: "Test title"
}
I’ve searched everywhere for a solution. Everywhere on the internet they suggest to make an Exporter for my component:
@Model(adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
resourceType = {"mysite/components/public/carousel"})
@Exporter(name = "jackson", extensions = "json")
public class CarouselModelImpl implements CarouselModel, ComponentModel {
...
@Getter
private List<CarouselBean> slides;
...
So when I visit
homepage/jcr:content/carousel.model.json I get the correct JSON:
{
title: "Test title",
slides: [
{
title: "slide title 1",
description: null,
ctaLabel: "cta label",
ctaLink: "#",
image: "/content/dam/mysite/Rectangle 2.png"
},
{
title: "slide title 2",
description: null,
ctaLabel: "cta label",
ctaLink: "#",
image: "/content/dam/mysite/image.png"
}
],
}
But when I visit the homepage.model.json it’s still not included:
carousel: {
:type: "mysite/components/public/carousel",
title: "Test title"
}
So from what I understand I have 2 options:
-
To make a Page Exporter and have a lot of custom code.
-
Accept that I can’t have a page with all the JSON data that I want.
I tried to make a custom Page Exporter with the logic to iterate all the children and sub-children in order to get the correct JSON with minimal code. I try to get the Exporter Models for each component, but the modelFactory is null
.
@Model(adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
resourceType = {"mysite/components/public/structure/public-page"})
@Exporter(name = "jackson", extensions = "json")
public class PageExporterServlet {
private static final Logger log = LoggerFactory.getLogger(PageUtils.class);
@Reference
private ModelFactory modelFactory;
@Reference
private SlingScriptHelper slingScriptHelper;
@Self
private Resource resource;
@Getter
private String myTitle = "Test";
@Getter
Map<String, Object> pageData = new HashMap<>();
@PostConstruct
// PostConstructs are called after all the injection has occurred, but before the Model object is returned for use.
protected void init() {
try {
processResource(resource, pageData);
} catch (Exception e) {
log.debug(e.getMessage());
}
}
private void processResource(Resource resource, Map<String, Object> pageData) {
if (resource != null) {
Iterable<Resource> childResources = resource.getChildren();
for (Resource childResource : childResources) {
ComponentModel componentModel = (ComponentModel) modelFactory.getModelFromResource(childResource);
if (componentModel != null) {
pageData.put(childResource.getPath(), componentModel.getData());
} else {
// If the resource is not a component, recursively process its children
processResource(childResource, pageData);
}
}
}
}
}