From: Banana Date: Tue, 12 Sep 2023 09:24:31 +0000 (+0200) Subject: adding custom area rendering for magnolia X-Git-Url: http://91.132.146.200/gitweb/?a=commitdiff_plain;h=fa01fa811486d08386229a64edb04fb08f08d389;p=klimbim.git adding custom area rendering for magnolia --- diff --git a/magnolia/customAreaRendering/VirtualPageModel.java b/magnolia/customAreaRendering/VirtualPageModel.java new file mode 100644 index 0000000..610151c --- /dev/null +++ b/magnolia/customAreaRendering/VirtualPageModel.java @@ -0,0 +1,114 @@ +package custom.package; + +import info.magnolia.context.MgnlContext; +import info.magnolia.jcr.util.ContentMap; +import info.magnolia.jcr.util.NodeTypes; +import info.magnolia.jcr.util.NodeUtil; +import info.magnolia.rendering.engine.AppendableOnlyOutputProvider; +import info.magnolia.rendering.engine.RenderException; +import info.magnolia.rendering.engine.RenderingEngine; +import info.magnolia.rendering.model.RenderingModel; +import info.magnolia.rendering.model.RenderingModelImpl; +import info.magnolia.rendering.template.AreaDefinition; +import info.magnolia.rendering.template.TemplateDefinition; +import info.magnolia.rendering.template.assignment.TemplateDefinitionAssignment; +import info.magnolia.rendering.template.configured.ConfiguredTemplateDefinition; +import info.magnolia.repository.RepositoryConstants; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import javax.jcr.Node; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This is an example for a custom model class which loads the main area content + * from a referenced page. Without any content duplication + * Use the mainContent to display the result in the FTL + * + * It uses all the templates of the components and the main area templates + * Thus "rendering" the content into a string. The content which would be the answer + * to a client request + * + * Usefull also in custom rest endpoints + * + * Currently only the main area is used. If there are more, it needs some work + */ + + +public class VirtualPageModel extends RenderingModelImpl { + + private static final Logger log = LoggerFactory.getLogger(VirtualPageModel.class); + + private final TemplateDefinitionAssignment templateAssignment; + private final RenderingEngine renderingEngine; + + @Getter + private String mainContent = StringUtils.EMPTY; + + @Inject + public VirtualPageModel(Node content, + ConfiguredTemplateDefinition definition, + RenderingModel parent, + TemplateDefinitionAssignment templateAssignment, + RenderingEngine renderingEngine) { + super(content, definition, parent); + this.templateAssignment = templateAssignment; + this.renderingEngine = renderingEngine; + + getContent(); // init contentMap + this.contentFromRefPage(); + } + + /** + * Load the main area nodes from referenced page and build the are as string to use in ftl + * + */ + private void contentFromRefPage() { + if(contentMap.containsKey("propertyWithReferencedUUIDinIt")) { + String refUUID = contentMap.get("propertyWithReferencedUUIDinIt").toString(); + log.debug("Referenced uuid given {}", refUUID); + try { + OutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(outputStream); + AppendableOnlyOutputProvider appendable = new AppendableOnlyOutputProvider(writer); + + Node referencedNode = NodeUtil.getNodeByIdentifier(RepositoryConstants.WEBSITE, refUUID); + Node referencesMainNode = referencedNode.getNode("main"); + + List listOfComponents = NodeUtil.asList(NodeUtil.getNodes(referencesMainNode, NodeTypes.Component.NAME)); + List components = new ArrayList(); + for (Node node : listOfComponents) { + components.add(new ContentMap(node)); + } + Map contextObjects = new HashMap(); + contextObjects.put("components", components); + + TemplateDefinition mainDef = templateAssignment.getAssignedTemplateDefinition(referencedNode); + Map areas = mainDef.getAreas(); + // limitation to only one area right now. + try { + renderingEngine.render(referencesMainNode, areas.get("main"), contextObjects, appendable); + } catch (RenderException e) { + throw new RuntimeException(e); + } + + ((Writer) appendable.getAppendable()).flush(); + + mainContent = outputStream.toString(); + + } catch (Exception e) { + log.warn("Can not resolve given page with uuid {} for virtual page {}", refUUID, contentMap.get("uuid")); + } + } + } +}