1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.templating.elements;
35
36 import info.magnolia.cms.beans.config.ServerConfiguration;
37 import info.magnolia.cms.i18n.Messages;
38 import info.magnolia.cms.i18n.MessagesManager;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.context.WebContext;
41 import info.magnolia.jcr.inheritance.InheritanceNodeWrapper;
42 import info.magnolia.registry.RegistrationException;
43 import info.magnolia.rendering.context.RenderingContext;
44 import info.magnolia.rendering.engine.AppendableOnlyOutputProvider;
45 import info.magnolia.rendering.engine.RenderException;
46 import info.magnolia.rendering.engine.RenderingEngine;
47 import info.magnolia.rendering.template.TemplateDefinition;
48 import info.magnolia.rendering.template.assignment.TemplateDefinitionAssignment;
49 import info.magnolia.templating.freemarker.AreaDirective;
50
51 import java.io.IOException;
52 import java.util.HashMap;
53 import java.util.Map;
54
55 import javax.inject.Inject;
56 import javax.jcr.Node;
57
58 import org.apache.commons.lang.StringUtils;
59
60
61
62
63
64
65 public class ComponentElement extends AbstractContentTemplatingElement {
66
67 private Map<String, Object> contextAttributes = new HashMap<String, Object>();
68 private final RenderingEngine renderingEngine;
69 private Node content;
70 private final TemplateDefinitionAssignment templateDefinitionAssignment;
71 private TemplateDefinition componentDefinition;
72
73 private String dialog;
74 private Boolean editable;
75
76 @Inject
77 public ComponentElement(ServerConfiguration server, RenderingContext renderingContext, RenderingEngine renderingEngine, TemplateDefinitionAssignment templateDefinitionAssignment ) {
78 super(server, renderingContext);
79 this.renderingEngine = renderingEngine;
80 this.templateDefinitionAssignment = templateDefinitionAssignment;
81 }
82
83 @Override
84 public void begin(Appendable out) throws IOException, RenderException {
85
86 content = getPassedContent();
87
88 if(content == null) {
89 throw new RenderException("The 'content' or 'workspace' and 'path' attribute have to be set to rendre a component.");
90 }
91
92 if(isAdmin()){
93 MarkupHelper helper = new MarkupHelper(out);
94
95 helper.openComment("cms:component");
96
97
98 helper.attribute(AreaDirective.CONTENT_ATTRIBUTE, getNodePath(content));
99
100 if(content instanceof InheritanceNodeWrapper) {
101 if (((InheritanceNodeWrapper) content).isInherited()) {
102 helper.attribute("inherited", "true");
103 }
104 }
105 try {
106 this.componentDefinition = templateDefinitionAssignment.getAssignedTemplateDefinition(content);
107 } catch (RegistrationException e) {
108 throw new RenderException("No template definition found for the current content", e);
109 }
110
111 final Messages messages = MessagesManager.getMessages(componentDefinition.getI18nBasename());
112
113 this.editable = resolveEditable();
114 if (this.editable != null) {
115 helper.attribute("editable", String.valueOf(this.editable));
116 }
117
118 if(StringUtils.isEmpty(dialog)) {
119 dialog = resolveDialog();
120 }
121 helper.attribute("dialog", dialog);
122
123 String label = StringUtils.defaultIfEmpty(componentDefinition.getTitle(),componentDefinition.getName());
124 helper.attribute("label", messages.getWithDefault(label, label));
125
126 if(StringUtils.isNotEmpty(componentDefinition.getDescription())){
127 helper.attribute("description", componentDefinition.getDescription());
128 }
129 helper.append(" -->\n");
130 }
131
132
133
134 WebContext webContext = MgnlContext.getWebContext();
135 webContext.push(webContext.getRequest(), webContext.getResponse());
136 setAttributesInWebContext(contextAttributes, WebContext.LOCAL_SCOPE);
137
138
139 try {
140 if(componentDefinition != null) {
141 renderingEngine.render(content, componentDefinition, new HashMap<String, Object>(), new AppendableOnlyOutputProvider(out));
142 } else {
143 renderingEngine.render(content, new AppendableOnlyOutputProvider(out));
144 }
145 } finally {
146 webContext.pop();
147 webContext.setPageContext(null);
148 restoreAttributesInWebContext(contextAttributes, WebContext.LOCAL_SCOPE);
149 }
150 }
151
152 private Boolean resolveEditable() {
153 return editable != null ? editable : componentDefinition != null && componentDefinition.getEditable() != null ? componentDefinition.getEditable() : null;
154 }
155
156 @Override
157 public void end(Appendable out) throws IOException, RenderException {
158 if(isAdmin()){
159 new MarkupHelper(out).closeComment("cms:component");
160 }
161 }
162
163 public Map<String, Object> getContextAttributes() {
164 return contextAttributes;
165 }
166
167 public void setContextAttributes(Map<String, Object> contextAttributes) {
168 this.contextAttributes = contextAttributes;
169 }
170
171 private String resolveDialog() {
172 if (StringUtils.isNotEmpty(this.dialog)) {
173 return this.dialog;
174 }
175 String dialog = componentDefinition.getDialog();
176 if (StringUtils.isNotEmpty(dialog)) {
177 return dialog;
178 }
179 return null;
180 }
181
182 public void setDialog(String dialog) {
183 this.dialog = dialog;
184 }
185
186 public void setEditable(Boolean editable) {
187 this.editable = editable;
188 }
189
190 public Boolean getEditable() {
191 return editable;
192 }
193 }