1
0

VirtualPageModel.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package custom.package;
  2. import info.magnolia.context.MgnlContext;
  3. import info.magnolia.jcr.util.ContentMap;
  4. import info.magnolia.jcr.util.NodeTypes;
  5. import info.magnolia.jcr.util.NodeUtil;
  6. import info.magnolia.rendering.engine.AppendableOnlyOutputProvider;
  7. import info.magnolia.rendering.engine.RenderException;
  8. import info.magnolia.rendering.engine.RenderingEngine;
  9. import info.magnolia.rendering.model.RenderingModel;
  10. import info.magnolia.rendering.model.RenderingModelImpl;
  11. import info.magnolia.rendering.template.AreaDefinition;
  12. import info.magnolia.rendering.template.TemplateDefinition;
  13. import info.magnolia.rendering.template.assignment.TemplateDefinitionAssignment;
  14. import info.magnolia.rendering.template.configured.ConfiguredTemplateDefinition;
  15. import info.magnolia.repository.RepositoryConstants;
  16. import lombok.Getter;
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20. import javax.inject.Inject;
  21. import javax.jcr.Node;
  22. import java.io.ByteArrayOutputStream;
  23. import java.io.OutputStream;
  24. import java.io.OutputStreamWriter;
  25. import java.io.Writer;
  26. import java.util.ArrayList;
  27. import java.util.HashMap;
  28. import java.util.List;
  29. import java.util.Map;
  30. /**
  31. * This is an example for a custom model class which loads the main area content
  32. * from a referenced page. Without any content duplication
  33. * Use the mainContent to display the result in the FTL
  34. *
  35. * It uses all the templates of the components and the main area templates
  36. * Thus "rendering" the content into a string. The content which would be the answer
  37. * to a client request
  38. *
  39. * Usefull also in custom rest endpoints
  40. *
  41. * Currently only the main area is used. If there are more, it needs some work
  42. */
  43. public class VirtualPageModel<RD extends ConfiguredTemplateDefinition> extends RenderingModelImpl<ConfiguredTemplateDefinition> {
  44. private static final Logger log = LoggerFactory.getLogger(VirtualPageModel.class);
  45. private final TemplateDefinitionAssignment templateAssignment;
  46. private final RenderingEngine renderingEngine;
  47. @Getter
  48. private String mainContent = StringUtils.EMPTY;
  49. @Inject
  50. public VirtualPageModel(Node content,
  51. ConfiguredTemplateDefinition definition,
  52. RenderingModel<?> parent,
  53. TemplateDefinitionAssignment templateAssignment,
  54. RenderingEngine renderingEngine) {
  55. super(content, definition, parent);
  56. this.templateAssignment = templateAssignment;
  57. this.renderingEngine = renderingEngine;
  58. getContent(); // init contentMap
  59. this.contentFromRefPage();
  60. }
  61. /**
  62. * Load the main area nodes from referenced page and build the are as string to use in ftl
  63. *
  64. */
  65. private void contentFromRefPage() {
  66. if(contentMap.containsKey("propertyWithReferencedUUIDinIt")) {
  67. String refUUID = contentMap.get("propertyWithReferencedUUIDinIt").toString();
  68. log.debug("Referenced uuid given {}", refUUID);
  69. try {
  70. OutputStream outputStream = new ByteArrayOutputStream();
  71. OutputStreamWriter writer = new OutputStreamWriter(outputStream);
  72. AppendableOnlyOutputProvider appendable = new AppendableOnlyOutputProvider(writer);
  73. Node referencedNode = NodeUtil.getNodeByIdentifier(RepositoryConstants.WEBSITE, refUUID);
  74. Node referencesMainNode = referencedNode.getNode("main");
  75. List<Node> listOfComponents = NodeUtil.asList(NodeUtil.getNodes(referencesMainNode, NodeTypes.Component.NAME));
  76. List<ContentMap> components = new ArrayList<ContentMap>();
  77. for (Node node : listOfComponents) {
  78. components.add(new ContentMap(node));
  79. }
  80. Map<String, Object> contextObjects = new HashMap<String, Object>();
  81. contextObjects.put("components", components);
  82. TemplateDefinition mainDef = templateAssignment.getAssignedTemplateDefinition(referencedNode);
  83. Map<String, AreaDefinition> areas = mainDef.getAreas();
  84. // limitation to only one area right now.
  85. try {
  86. renderingEngine.render(referencesMainNode, areas.get("main"), contextObjects, appendable);
  87. } catch (RenderException e) {
  88. throw new RuntimeException(e);
  89. }
  90. ((Writer) appendable.getAppendable()).flush();
  91. mainContent = outputStream.toString();
  92. } catch (Exception e) {
  93. log.warn("Can not resolve given page with uuid {} for virtual page {}", refUUID, contentMap.get("uuid"));
  94. }
  95. }
  96. }
  97. }