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"]}
+ #if>
+#macro>
+
+<#macro main item>
+ <#if (item["./textAsset"]?size > 0)>
+ ${item["./textAsset/content"]}
+ #if>
+#macro>
\ 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 @@
#if>
#macro>
+
+<#macro greetingItem>
+
+ <#nested model["/bebop:page/nav:greetingItem/cms:item"]>
+
+#macro>
\ 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);
+ }
+
}