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.functions;
35
36 import static com.google.common.base.Preconditions.checkArgument;
37
38 import info.magnolia.cms.core.Path;
39 import info.magnolia.jcr.util.ContentMap;
40 import info.magnolia.jcr.util.NodeTypes;
41 import info.magnolia.jcr.util.NodeUtil;
42 import info.magnolia.link.Link;
43 import info.magnolia.link.LinkTransformerManager;
44 import info.magnolia.link.LinkUtil;
45 import info.magnolia.templating.predicates.NavigationItemPredicate;
46
47 import java.util.Collections;
48 import java.util.List;
49
50 import javax.inject.Inject;
51 import javax.inject.Singleton;
52 import javax.jcr.Node;
53 import javax.jcr.RepositoryException;
54
55 import org.apache.commons.lang3.StringUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63
64
65
66
67
68 @Singleton
69 public class NavigationTemplatingFunctions {
70
71 private static final Logger log = LoggerFactory.getLogger(NavigationTemplatingFunctions.class);
72
73 public static final String HIDE_IN_NAVIGATION_PROPERTY_NAME = "hideInNav";
74
75 private final TemplatingFunctions templatingFunctions;
76
77 @Inject
78 public NavigationTemplatingFunctions(TemplatingFunctions templatingFunctions) {
79 this.templatingFunctions = templatingFunctions;
80 }
81
82
83
84
85
86
87
88
89
90 public ContentMap rootPage(ContentMap page) throws RepositoryException {
91 if (page == null) {
92 return null;
93 }
94 Node node = page.getJCRNode();
95 if (node.getDepth() == 1) {
96 if (node.isNodeType(NodeTypes.Page.NAME)) {
97 return page;
98 } else {
99 return null;
100 }
101 }
102 return templatingFunctions.root(page, NodeTypes.Page.NAME);
103 }
104
105
106
107
108
109
110
111
112
113
114
115 public ContentMap ancestorPageAtLevel(ContentMap page, int depth) throws RepositoryException {
116 if (page == null) {
117 return null;
118 }
119 Node node = page.getJCRNode();
120 if (node.getDepth() >= depth) {
121 Node ancestor = (Node) node.getAncestor(depth);
122 if (ancestor.isNodeType(NodeTypes.Page.NAME)) {
123 return templatingFunctions.asContentMap(ancestor);
124 }
125 }
126 return null;
127 }
128
129
130
131
132
133
134
135
136 public List<ContentMap> navItems(ContentMap page) throws RepositoryException {
137 if (page == null) {
138 return Collections.emptyList();
139 }
140 return templatingFunctions.asContentMapList(NodeUtil.getNodes(page.getJCRNode(), new NavigationItemPredicate()));
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 public List<ContentMap> navItemsFromApp(String workspace, String parentPath, String nodeType) throws RepositoryException {
166 checkArgument(StringUtils.isNotBlank(workspace), "Workspace has to be specified.");
167 checkArgument(StringUtils.isNotBlank(parentPath), "ParentPath is not specified.");
168 checkArgument(StringUtils.isNotBlank(nodeType), "NodeType is not specified.");
169
170 Node content = templatingFunctions.nodeByPath(parentPath, workspace);
171 if (content == null) {
172 log.warn("Can't resolve parent item for navigation from app: workspace [{}], path [{}]", workspace, parentPath);
173 return Collections.emptyList();
174 }
175 return templatingFunctions.asContentMapList(NodeUtil.getNodes(content, new NavigationItemPredicate(nodeType)));
176 }
177
178
179
180
181 public boolean hasTemplate(ContentMap page, String template) throws RepositoryException {
182 return template != null && page != null && template.equals(NodeTypes.Renderable.getTemplate(page.getJCRNode()));
183 }
184
185
186
187
188 public boolean hasTemplateType(ContentMap page, String templateType) throws RepositoryException {
189 return templateType != null && page != null && templateType.equals(templatingFunctions.templateType(page));
190 }
191
192
193
194
195 public boolean hasTemplateSubtype(ContentMap page, String templateSubtype) throws RepositoryException {
196 return templateSubtype != null && page != null && templateSubtype.equals(templatingFunctions.templateSubtype(page));
197 }
198
199
200
201
202
203
204
205
206
207
208
209 public String linkWithSelector(ContentMap targetPage, ContentMap content) throws RepositoryException {
210 if (targetPage == null || content == null) {
211 return null;
212 }
213 Node pageNode = targetPage.getJCRNode();
214 Node contentNode = content.getJCRNode();
215
216 Link pageLinkInstance = LinkUtil.createLinkInstance(pageNode);
217 String pageLink = LinkTransformerManager.getInstance().getBrowserLink(pageNode.getPath()).transform(pageLinkInstance);
218 String extension = pageLinkInstance.getExtension();
219 if (StringUtils.isEmpty(extension)) {
220 return pageLink + Path.SELECTOR_DELIMITER + contentNode.getName() + Path.SELECTOR_DELIMITER;
221 } else {
222 return StringUtils.substringBeforeLast(pageLink, ".") + Path.SELECTOR_DELIMITER + contentNode.getName() + Path.SELECTOR_DELIMITER + "." + extension;
223 }
224 }
225
226
227
228
229
230
231
232
233 public String linkWithParameter(ContentMap targetPage, ContentMap content) throws RepositoryException {
234 if (content == null) {
235 return null;
236 }
237 return linkWithParameter(targetPage, content, content.getJCRNode().getSession().getWorkspace().getName());
238 }
239
240
241
242
243
244
245
246
247
248 public String linkWithParameter(ContentMap targetPage, ContentMap content, String parameterName) throws RepositoryException {
249 if (targetPage == null || content == null) {
250 return null;
251 }
252 Node pageNode = targetPage.getJCRNode();
253 Node contentNode = content.getJCRNode();
254
255 Link pageLinkInstance = LinkUtil.createLinkInstance(pageNode);
256 pageLinkInstance.setParameters(parameterName + "=" + contentNode.getName());
257 return LinkTransformerManager.getInstance().getBrowserLink(pageNode.getPath()).transform(pageLinkInstance);
258 }
259
260
261
262
263 public String link(ContentMap content) throws RepositoryException {
264 return templatingFunctions.link(content);
265 }
266
267
268
269
270
271
272 public boolean isActive(ContentMap content, ContentMap navigationItem) throws RepositoryException {
273 if (content == null || navigationItem == null) {
274 return false;
275 }
276 Node activePageNode = templatingFunctions.page(content.getJCRNode());
277 return navigationItem.getJCRNode().isSame(activePageNode);
278 }
279
280
281
282
283
284
285 public boolean isOpen(ContentMap content, ContentMap navigationItem) throws RepositoryException {
286 if (content == null || navigationItem == null) {
287 return false;
288 }
289 String activePagePath = templatingFunctions.page(content.getJCRNode()).getPath();
290 String navigationItemPath = navigationItem.getJCRNode().getPath();
291 return !StringUtils.equals(activePagePath, navigationItemPath) && StringUtils.startsWith(activePagePath, navigationItemPath);
292 }
293
294
295
296
297
298
299
300 public boolean isHiddenInNav(ContentMap content) throws RepositoryException {
301 if (content == null) {
302 return false;
303 }
304 Node node = content.getJCRNode();
305 return node.hasProperty(HIDE_IN_NAVIGATION_PROPERTY_NAME) && node.getProperty(HIDE_IN_NAVIGATION_PROPERTY_NAME).getBoolean();
306 }
307
308
309
310
311 public boolean isNotHiddenInNav(ContentMap content) throws RepositoryException {
312 return !isHiddenInNav(content);
313 }
314
315
316
317
318
319 public boolean isTrue(ContentMap content, String propertyName) throws RepositoryException {
320 if (content == null || StringUtils.isBlank(propertyName)) {
321 return false;
322 }
323 Node node = content.getJCRNode();
324 return node.hasProperty(propertyName) && node.getProperty(propertyName).getBoolean();
325 }
326 }