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.module.templatingkit.functions;
35
36 import info.magnolia.context.MgnlContext;
37 import info.magnolia.dam.DamManager;
38 import info.magnolia.dam.asset.Asset;
39 import info.magnolia.dam.asset.functions.DamTemplatingFunctions;
40 import info.magnolia.dam.asset.renderer.NoSuchRenditionException;
41 import info.magnolia.dam.provider.AssetProviderNotFoundException;
42 import info.magnolia.dam.providers.jcr.JcrAssetProvider;
43 import info.magnolia.jcr.util.ContentMap;
44 import info.magnolia.jcr.util.NodeTypes;
45 import info.magnolia.jcr.util.NodeUtil;
46 import info.magnolia.jcr.util.PropertyUtil;
47 import info.magnolia.jcr.wrapper.I18nNodeWrapper;
48 import info.magnolia.module.templatingkit.STKModule;
49 import info.magnolia.module.templatingkit.categorization.CategorizationSupport;
50 import info.magnolia.module.templatingkit.imaging.ImagingSupport;
51 import info.magnolia.module.templatingkit.sites.Site;
52 import info.magnolia.module.templatingkit.sites.SiteManager;
53 import info.magnolia.module.templatingkit.style.CssSelectorBuilder;
54 import info.magnolia.module.templatingkit.style.Theme;
55 import info.magnolia.module.templatingkit.style.ThemeImpl;
56 import info.magnolia.module.templatingkit.templates.AbstractSTKTemplateModel;
57 import info.magnolia.module.templatingkit.templates.category.TemplateCategory;
58 import info.magnolia.module.templatingkit.templates.category.TemplateCategoryUtil;
59 import info.magnolia.rendering.template.TemplateDefinition;
60 import info.magnolia.repository.RepositoryConstants;
61 import info.magnolia.templating.functions.TemplatingFunctions;
62
63 import java.util.ArrayList;
64 import java.util.List;
65 import java.util.Set;
66
67 import javax.inject.Inject;
68 import javax.inject.Provider;
69 import javax.inject.Singleton;
70 import javax.jcr.Node;
71 import javax.jcr.RepositoryException;
72
73 import org.apache.commons.lang.StringUtils;
74 import org.apache.commons.lang.mutable.MutableInt;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
77
78
79
80
81
82 @Singleton
83 public class STKTemplatingFunctions {
84
85 private static Logger log = LoggerFactory.getLogger(STKTemplatingFunctions.class);
86
87 public static final String SITEROOT_TEMPLATE_CATEGORY = TemplateCategory.HOME;
88
89 protected static final String TITLE_PROP_NAME = "title";
90 protected static final String SITE_TITLE_PROP_NAME = "siteTitle";
91
92
93 private CssSelectorBuilder cssSelectorBuilder;
94 private CategorizationSupport categorizationSupport;
95 private final SiteManager siteManager;
96 private final TemplatingFunctions templatingFunctions;
97 private final Provider<STKModule> moduleProvider;
98 private final DamTemplatingFunctions damFunctions;
99 private final DamManager damManager;
100
101 @Inject
102 public STKTemplatingFunctions(TemplatingFunctions templatingFunctions, CssSelectorBuilder cssSelectorBuilder, CategorizationSupport categorizationSupport, SiteManager siteManager,
103 Provider<STKModule> moduleProvider, DamManager damManager, DamTemplatingFunctions damFunctions) {
104 this.templatingFunctions = templatingFunctions;
105 this.cssSelectorBuilder = cssSelectorBuilder;
106 this.categorizationSupport = categorizationSupport;
107 this.siteManager = siteManager;
108 this.moduleProvider = moduleProvider;
109 this.damFunctions = damFunctions;
110 this.damManager = damManager;
111 }
112
113
114
115
116
117
118
119
120
121
122
123 public String searchPageLink(Node content) {
124 String searchResultPageUUID = PropertyUtil.getString(siteRoot(content), "searchUUID");
125 return (StringUtils.isEmpty(searchResultPageUUID)) ? null : templatingFunctions.link(RepositoryConstants.WEBSITE, searchResultPageUUID);
126 }
127
128 public String searchPageLink(ContentMap content) {
129 return searchPageLink(content.getJCRNode());
130 }
131
132
133
134
135 public String homeName(Node content) {
136 return NodeUtil.getName(siteRoot(content));
137 }
138
139 public String homeName(ContentMap content) {
140 return homeName(content.getJCRNode());
141 }
142
143
144
145
146
147 public String homeTitle(Node content) {
148 return PropertyUtil.getString(siteRoot(content), TITLE_PROP_NAME);
149 }
150
151 public String homeTitle(ContentMap content) {
152 return homeTitle(content.getJCRNode());
153 }
154
155
156
157
158
159 public String siteTitle(Node content) {
160 return PropertyUtil.getString(siteRoot(content), SITE_TITLE_PROP_NAME);
161 }
162
163 public String siteTitle(ContentMap content) {
164 return siteTitle(content.getJCRNode());
165 }
166
167
168
169
170 public String homeLink(Node content) {
171 return templatingFunctions.link(siteRoot(content));
172 }
173
174 public String homeLink(ContentMap content) {
175 return homeLink(content.getJCRNode());
176 }
177
178 public Site site() {
179 return siteManager.getCurrentSite();
180 }
181
182
183
184
185
186
187
188
189
190 public Site site(Node content) {
191 try {
192 return (content == null) ? null : siteManager.getAssignedSite(content);
193 } catch (IllegalStateException e) {
194 log.error("Unable to access assigned site ({}) until following issue is resolved: {}", content.toString(), e.getMessage());
195 return null;
196 }
197 }
198
199
200
201
202
203 public Theme theme(Site site) {
204 final String theme = site.getTheme().getName();
205 return StringUtils.isBlank(theme) ? new ThemeImpl() : moduleProvider.get().getTheme(theme);
206
207 }
208
209
210
211
212
213
214
215
216
217
218 public Site site(ContentMap content) {
219 return site(content.getJCRNode());
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233 public Node siteRoot(Node content) {
234 return this.siteRoot(content, SITEROOT_TEMPLATE_CATEGORY);
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248
249 public ContentMap siteRoot(ContentMap content) {
250 return this.siteRoot(content, SITEROOT_TEMPLATE_CATEGORY);
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 public ContentMap siteRoot(ContentMap content, String siteRootTemplateCategory) {
270 return templatingFunctions.asContentMap(siteRoot(content.getJCRNode(), siteRootTemplateCategory));
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290 public Node siteRoot(Node content, String siteRootTemplateCategory) {
291 if (StringUtils.isEmpty(siteRootTemplateCategory)) {
292 siteRootTemplateCategory = SITEROOT_TEMPLATE_CATEGORY;
293 }
294 try {
295 Node page = this.templatingFunctions.page(content);
296 Node root = TemplateCategoryUtil.findParentWithTemplateCategory(page, siteRootTemplateCategory);
297 return (root == null) ? (Node) page.getAncestor(0) : root;
298 } catch (RepositoryException e) {
299 throw new RuntimeException("Can't access site root.", e);
300 }
301 }
302
303 public List<ContentMap> ancestorsInSite(ContentMap content) throws RepositoryException {
304 return ancestorsInSite(content, null);
305 }
306
307 public List<Node> ancestorsInSite(Node content) throws RepositoryException {
308 return ancestorsInSite(content, null);
309 }
310
311 public List<ContentMap> ancestorsInSite(ContentMap content, String nodeTypeName) throws RepositoryException {
312 return templatingFunctions.asContentMapList(ancestorsInSite(content.getJCRNode(), nodeTypeName));
313 }
314
315 public List<Node> ancestorsInSite(Node content, String nodeTypeName) throws RepositoryException {
316 List<Node> allAncestors = templatingFunctions.ancestors(content, nodeTypeName);
317 Node siteRoot = siteRoot(content);
318
319 List<Node> ancestoresInSite = new ArrayList<Node>();
320 for (Node current : allAncestors) {
321 if (current.getDepth() >= siteRoot.getDepth()) {
322 ancestoresInSite.add(current);
323 }
324 }
325 return ancestoresInSite;
326 }
327
328
329
330
331
332 public String getAssetLink(Node content, String assetProperty) {
333 return getAssetLink(content, assetProperty, ImagingSupport.VARIATION_ORIGINAL);
334 }
335
336
337
338
339
340 public String getAssetLink(ContentMap content, String assetProperty) {
341 return getAssetLink(content.getJCRNode(), assetProperty);
342 }
343
344
345
346
347
348
349 public String getAssetLink(ContentMap content, String assetProperty, AbstractSTKTemplateModel<? extends TemplateDefinition> model) {
350 return getAssetLink(content.getJCRNode(), assetProperty, resolveImageVariationName(model));
351 }
352
353
354
355
356
357 public String getAssetLink(ContentMap content, String assetProperty, String renditionName) {
358 return getAssetLink(content.getJCRNode(), assetProperty, renditionName);
359 }
360
361
362
363
364
365 public String getAssetLink(Node content, String assetProperty, String renditionName) {
366
367 String assetIdentifier = PropertyUtil.getString(content, assetProperty);
368 if (StringUtils.isNotBlank(assetIdentifier)) {
369 return damFunctions.getAssetLinkForId(assetIdentifier, renditionName);
370 }
371 return null;
372 }
373
374 public String resolveImageVariationName(AbstractSTKTemplateModel<? extends TemplateDefinition> model) {
375 final String cssSelector = cssSelectorBuilder.createCssSelector(model);
376 try {
377 return theme(site(model.getNode())).getImaging().resolveVariationName(cssSelector);
378 } catch (NoSuchRenditionException e) {
379 log.warn(e.getMessage());
380 return ImagingSupport.VARIATION_ORIGINAL;
381 }
382 }
383
384
385
386
387
388 public Asset getAssetVariation(Asset asset, String renditionName) {
389 return damFunctions.getAssetRendition(asset, renditionName);
390 }
391
392
393
394
395
396 public Node wrap(Node content) {
397 return (content == null) ? null : templatingFunctions.encode(new I18nNodeWrapper(content));
398 }
399
400
401
402
403 public List<ContentMap> getCategories(Node page) {
404 return categorizationSupport.getCategories(page);
405 }
406
407
408
409
410 public String getCategoryLink(Node page, String categoryName) {
411 return categorizationSupport.getCategoryLink(page, categoryName);
412 }
413
414
415
416
417 public List<Node> getContentListByTemplateCategorySubCategory(Node siteRoot, String category, String subCategory) throws RepositoryException {
418 return getContentListByTemplateCategorySubCategory(siteRoot, category, subCategory, Integer.MAX_VALUE, null, null);
419 }
420
421
422
423
424 public static List<Node> getContentListByTemplateCategorySubCategory(Node siteRoot, String category, String subCategory, int maxResultSize, String andClause, String orderBy)
425 throws RepositoryException {
426 return TemplateCategoryUtil.getContentListByTemplateCategorySubCategory(siteRoot, category, subCategory, maxResultSize, andClause, orderBy);
427 }
428
429
430
431
432 public Node getNearestContentByTemplateCategorySubCategory(Node siteRoot, String category, String subCategory, Node current) throws RepositoryException {
433 return TemplateCategoryUtil.getNearestContentByTemplateCategorySubCategory(siteRoot, category, subCategory, current);
434 }
435
436
437
438
439 public static List<Node> getContentListByTemplateName(Node searchRoot, String templateName) throws RepositoryException {
440 return TemplateCategoryUtil.getContentListByTemplateName(searchRoot, templateName);
441 }
442
443
444
445
446 public static List<Node> getContentListByTemplateName(Node searchRoot, String templateName, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
447 return TemplateCategoryUtil.getContentListByTemplateName(searchRoot, templateName, maxResultSize, andClause, orderByClause);
448 }
449
450
451
452
453 public static List<Node> getContentListByTemplateNames(Node searchRoot, Set<String> templateIds, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
454 return TemplateCategoryUtil.getContentListByTemplateNames(searchRoot, templateIds, maxResultSize, andClause, orderByClause);
455 }
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470 public Node getReferencedContent(Node content, String idPropertyName, String referencedWorkspace) throws RepositoryException {
471 if (content.hasProperty(idPropertyName)) {
472 String identifier = PropertyUtil.getString(content, idPropertyName);
473 return wrap(NodeUtil.getNodeByIdentifier(referencedWorkspace, identifier));
474 }
475 return null;
476 }
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495 public Asset getAsset(Node node, String assetProperty, String renditionName) {
496 Asset damAsset = null;
497 String providerId = null;
498 try {
499 if (node.hasProperty(assetProperty)) {
500 String assetNodeIdentifier = node.getProperty(assetProperty).getString();
501 return damFunctions.getAssetRenditionForAssetId(assetNodeIdentifier, renditionName);
502 }
503 } catch (RepositoryException e) {
504 log.warn("Could not find asset for '{}' at '{}'", new Object[] { assetProperty, NodeUtil.getNodePathIfPossible(node), e });
505 return null;
506 }
507 return null;
508 }
509
510
511
512
513
514 public Asset getAsset(Node content, String assetProperty) {
515 return getAsset(content, assetProperty, ImagingSupport.VARIATION_ORIGINAL);
516 }
517
518
519
520
521
522 public Asset getAsset(ContentMap content, String assetProperty) {
523 return getAsset(content.getJCRNode(), assetProperty);
524 }
525
526
527
528
529
530 public Asset getAsset(ContentMap content, String nodeDataPrefix, String variationName){
531 return getAsset(content.getJCRNode(), nodeDataPrefix, variationName);
532 }
533
534
535
536
537
538
539
540
541
542 public List<Asset> getAssetsFromFolder(Node node, String assetProperty) {
543
544 try {
545 if (node.hasProperty(assetProperty)) {
546 String folderIdentifier = node.getProperty(assetProperty).getString();
547 return damFunctions.getAssetsFromFolderId(folderIdentifier);
548 }
549 } catch (RepositoryException e) {
550 log.warn("Failed to get assets from folder.", e);
551 }
552
553 return new ArrayList<Asset>();
554 }
555
556
557
558
559
560
561
562
563 public List<Asset> getAssetsByQuery(String statement) {
564 try {
565 JcrAssetProvider assetProvider = (JcrAssetProvider) damManager.getAssetProvider(JcrAssetProvider.PROVIDER_ID);
566 return assetProvider.getAssetsByQuery(statement, false);
567 } catch (AssetProviderNotFoundException e) {
568 log.warn("Failed to query for assets.", e);
569 return new ArrayList<Asset>();
570 }
571 }
572
573
574
575
576
577 public List<Node> cutList(List<Node> itemsList, final int maxResults) {
578 if (itemsList.size() > maxResults) {
579 return itemsList.subList(0, maxResults);
580 }
581 return itemsList;
582 }
583
584
585 public String abbreviateString(String stringToCut, int size) {
586 return abbreviateString(stringToCut, size, " ...");
587 }
588
589 public String abbreviateString(String stringToCut, int size, String closureString) {
590 if (stringToCut.length() > size) {
591 int sizeMinusClosue = size - closureString.length();
592 String cuttedString = StringUtils.left(stringToCut, sizeMinusClosue);
593
594
595
596 String firstCharAfterCut = stringToCut.substring(sizeMinusClosue, sizeMinusClosue + 1);
597 if (!firstCharAfterCut.equals(" ")) {
598 cuttedString = StringUtils.substringBeforeLast(cuttedString, " ");
599 }
600
601 return cuttedString + closureString;
602
603 }
604 return stringToCut;
605 }
606
607
608
609
610
611 public int count(String name) {
612 String attributeName = STKTemplatingFunctions.class.getName() + name;
613 if (!MgnlContext.hasAttribute(attributeName)) {
614 MgnlContext.setAttribute(attributeName, new MutableInt(0));
615 }
616 MutableInt counter = (MutableInt) MgnlContext.getAttribute(attributeName);
617 counter.increment();
618 return counter.intValue();
619 }
620
621 public String getDivIdAbbreviation(String divID) {
622 return getDivIdAbbreviation(divID, "-");
623 }
624
625 public String getDivIdAbbreviation(String divID, String delimiter) {
626 String result = StringUtils.EMPTY;
627 if (StringUtils.isNotEmpty(divID) && StringUtils.isNotEmpty(delimiter)) {
628 String[] values = divID.split("\\" + delimiter);
629 for (String value : values) {
630 result += value.substring(0, 1);
631 }
632 }
633 return result;
634 }
635
636
637
638
639 public String metaDataProperty(Node content, String property) {
640 return templatingFunctions.metaData(content, property);
641 }
642
643 public String metaDataProperty(ContentMap content, String property) {
644 return templatingFunctions.metaData(content, property);
645 }
646
647
648
649
650
651 public String metaDataTemplate(Node content) {
652 try {
653 return NodeTypes.Renderable.getTemplate(content);
654 } catch (RepositoryException e) {
655 return null;
656 }
657 }
658
659 public String metaDataTemplate(ContentMap content) {
660 return metaDataTemplate(content.getJCRNode());
661 }
662
663
664
665
666 public void setCssSelectorBuilder(CssSelectorBuilder cssSelectorBuilder) {
667 this.cssSelectorBuilder = cssSelectorBuilder;
668 }
669
670
671
672
673 public void setCategorizationSupport(CategorizationSupport categorizationSupport) {
674 this.categorizationSupport = categorizationSupport;
675 }
676
677 }