From f71d08a24612b161ca93f224ef4be09c5289a0c3 Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 26 Feb 2019 18:45:10 +0000 Subject: [PATCH] Freemarker support for content items and ccm-cms-types-article * getting template for content item for theme manifest data * Freemarker macros for ** title for content item ** lead text of ccm-cms-types-article ** main text of ccm-cms-types-article git-svn-id: https://svn.libreccm.org/ccm/trunk@5840 8810af33-2d31-482b-a856-94f89814c4df --- .../ccm-cms-types-article/macros/article.ftl | 18 +++ .../ccm-navigation/macros/navigation.ftl | 6 + .../libreccm/theming/ContentItemTemplate.java | 6 +- .../libreccm/theming/ContentItemViews.java | 10 +- .../FreeMarkerPresentationManager.java | 140 +++++++++++++++++- 5 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 ccm-cms-types-article/web/themes/freemarker/ccm-cms-types-article/macros/article.ftl diff --git a/ccm-cms-types-article/web/themes/freemarker/ccm-cms-types-article/macros/article.ftl b/ccm-cms-types-article/web/themes/freemarker/ccm-cms-types-article/macros/article.ftl new file mode 100644 index 000000000..2bc18f26f --- /dev/null +++ b/ccm-cms-types-article/web/themes/freemarker/ccm-cms-types-article/macros/article.ftl @@ -0,0 +1,18 @@ +<#ftl ns_prefixes={ +"bebop":"http://www.arsdigita.com/bebop/1.0", +"cms":"http://www.arsdigita.com/cms/1.0", +"nav":"http://ccm.redhat.com/navigation", +"ui": "http://www.arsdigita.com/ui/1.0"} +> + +<#macro lead item> + <#if (item["./lead"]?size > 0)> + ${item["./lead"]} + + + +<#macro main item> + <#if (item["./textAsset"]?size > 0)> + ${item["./textAsset/content"]} + + \ No newline at end of file diff --git a/ccm-navigation/web/themes/freemarker/ccm-navigation/macros/navigation.ftl b/ccm-navigation/web/themes/freemarker/ccm-navigation/macros/navigation.ftl index e71745064..14e58d613 100644 --- a/ccm-navigation/web/themes/freemarker/ccm-navigation/macros/navigation.ftl +++ b/ccm-navigation/web/themes/freemarker/ccm-navigation/macros/navigation.ftl @@ -112,3 +112,9 @@ + +<#macro greetingItem> + + <#nested model["/bebop:page/nav:greetingItem/cms:item"]> + + \ No newline at end of file diff --git a/ccm-themedirector/src/org/libreccm/theming/ContentItemTemplate.java b/ccm-themedirector/src/org/libreccm/theming/ContentItemTemplate.java index bf235be16..187dfb5e8 100644 --- a/ccm-themedirector/src/org/libreccm/theming/ContentItemTemplate.java +++ b/ccm-themedirector/src/org/libreccm/theming/ContentItemTemplate.java @@ -12,7 +12,7 @@ import java.util.Objects; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlRootElement; /** * @@ -25,13 +25,13 @@ public class ContentItemTemplate { @XmlElement(name = "view", namespace = THEMES_XML_NS) private ContentItemViews view; - @XmlElement(name = "contenttype", namespace = THEMES_XML_NS) + @XmlElement(name = "contentType", namespace = THEMES_XML_NS) private String contentType; @XmlElement(name = "style", namespace = THEMES_XML_NS) private String style; - @XmlElement(name = "contentsection", namespace = THEMES_XML_NS) + @XmlElement(name = "contentSection", namespace = THEMES_XML_NS) private String contentSection; @XmlElement(name = "category", namespace = THEMES_XML_NS) diff --git a/ccm-themedirector/src/org/libreccm/theming/ContentItemViews.java b/ccm-themedirector/src/org/libreccm/theming/ContentItemViews.java index e62829390..4f757efc2 100644 --- a/ccm-themedirector/src/org/libreccm/theming/ContentItemViews.java +++ b/ccm-themedirector/src/org/libreccm/theming/ContentItemViews.java @@ -5,14 +5,22 @@ */ package org.libreccm.theming; +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; + /** * * @author Jens Pelzetter */ +@XmlEnum public enum ContentItemViews { - + + @XmlEnumValue(value = "detail") DETAIL, + @XmlEnumValue(value = "greetingItem") GREETING_ITEM, + @XmlEnumValue(value = "list") LIST, + @XmlEnumValue(value = "portletItemf") PORTLET_ITEM, } diff --git a/ccm-themedirector/src/org/libreccm/theming/FreeMarkerPresentationManager.java b/ccm-themedirector/src/org/libreccm/theming/FreeMarkerPresentationManager.java index 9c5b43013..912f34105 100644 --- a/ccm-themedirector/src/org/libreccm/theming/FreeMarkerPresentationManager.java +++ b/ccm-themedirector/src/org/libreccm/theming/FreeMarkerPresentationManager.java @@ -18,8 +18,12 @@ import freemarker.cache.TemplateLoader; import freemarker.cache.WebappTemplateLoader; import freemarker.ext.dom.NodeModel; import freemarker.template.Configuration; +import freemarker.template.SimpleScalar; import freemarker.template.Template; import freemarker.template.TemplateException; +import freemarker.template.TemplateMethodModelEx; +import freemarker.template.TemplateModelException; +import freemarker.template.TemplateScalarModel; import org.libreccm.theming.manifest.ThemeManifest; import org.libreccm.theming.manifest.ThemeManifestUtil; import org.w3c.dom.NamedNodeMap; @@ -30,6 +34,7 @@ import java.io.InputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; @@ -174,7 +179,7 @@ public class FreeMarkerPresentationManager implements PresentationManager { } else { applicationTemplatePath = templates.getDefaultApplicationTemplate(); } - + if ("XSL_FALLBACK.XSL".equals(applicationTemplatePath)) { final PageTransformer pageTransformer = new PageTransformer(); pageTransformer.servePage(document, request, response); @@ -195,6 +200,8 @@ public class FreeMarkerPresentationManager implements PresentationManager { // themePath); configuration.setTemplateLoader(templateLoader); configuration.setDefaultEncoding("UTF-8"); + configuration.setSharedVariable("getContentItemTemplate", + new GetContentItemTemplate(templates)); final Map data = new HashMap<>(); @@ -350,4 +357,135 @@ public class FreeMarkerPresentationManager implements PresentationManager { && template.getApplicationClass().equals(applicationClass); } + private class GetContentItemTemplate implements TemplateMethodModelEx { + + private final Templates templates; + + public GetContentItemTemplate(final Templates templates) { + this.templates = templates; + } + + @Override + public Object exec(final List list) throws TemplateModelException { + + if (list.isEmpty()) { + throw new IllegalArgumentException("GetContentItemTemplate " + + "requires the following parameters: " + + "item: NodeModel, view: String, style: String"); + } + + final Object arg0 = list.get(0); + if (!(arg0 instanceof NodeModel)) { + throw new IllegalArgumentException( + "Parameter item must be a NodeModel."); + } + final NodeModel itemModel = (NodeModel) arg0; + + final String view; + if (list.size() >= 2) { + view = ((TemplateScalarModel) list.get(1)) + .getAsString() + .toUpperCase(Locale.ROOT); + } else { + view = "DETAIL"; + } + final ContentItemViews contentItemView = ContentItemViews + .valueOf(view); + + final String style; + if (list.size() >= 3) { + style = ((TemplateScalarModel) list.get(2)).getAsString(); + } else { + style = ""; + } + + return findContentItemTemplate(templates, + itemModel, + contentItemView, + style); + } + + } + + private String findContentItemTemplate( + final Templates templates, + final NodeModel itemModel, + final ContentItemViews view, + final String style) throws TemplateModelException { + + final String contentType = ((TemplateScalarModel) itemModel + .get("objectType")) + .getAsString(); + + final Optional forTypeViewAndStyle = templates + .getContentItems() + .stream() + .filter(template -> filterContentItemTemplate(template, + contentType, + view, + style)) + .findAny(); + + if (forTypeViewAndStyle.isPresent()) { + return forTypeViewAndStyle.get().getTemplate(); + } else { + + final Optional forTypeAndView = templates + .getContentItems() + .stream() + .filter(template -> filterContentItemTemplate(template, + contentType, + view)) + .findAny(); + + if (forTypeAndView.isPresent()) { + return forTypeAndView.get().getTemplate(); + } else { + return templates.getDefaultContentItemsTemplate(); + } + } + + } + + private boolean filterContentItemTemplate( + final ContentItemTemplate template, + final String contentType, + final ContentItemViews view) { + + final ContentItemViews templateView; + if (template.getView() == null) { + templateView = ContentItemViews.DETAIL; + } else { + templateView = template.getView(); + } + + return template.getContentType().equals(contentType) + && templateView == view; + } + + private boolean filterContentItemTemplate( + final ContentItemTemplate template, + final String contentType, + final ContentItemViews view, + final String style) { + + final ContentItemViews templateView; + if (template.getView() == null) { + templateView = ContentItemViews.DETAIL; + } else { + templateView = template.getView(); + } + + final String templateStyle; + if (template.getStyle() == null) { + templateStyle = ""; + } else { + templateStyle = template.getStyle(); + } + + return template.getContentType().equals(contentType) + && templateView == view + && templateStyle.equals(style); + } + }