Date formatting for Freemarker themes
git-svn-id: https://svn.libreccm.org/ccm/trunk@5914 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
232587146d
commit
480e57816d
|
|
@ -36,9 +36,9 @@
|
|||
|
||||
<#function getNewsDate item>
|
||||
<#if (item["./newsDate"]?size > 0)>
|
||||
<#return item["./newsDate"].@@text />
|
||||
<#return item["./newsDate"] />
|
||||
<#elseif (item["./nav:attribute[@name='newsDate']"]?size > 0)>
|
||||
<#return item["./nav:attribute[@name='newsDate']"].@@text />
|
||||
<#return item["./nav:attribute[@name='newsDate']"] />
|
||||
</#if>
|
||||
</#function>
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import freemarker.template.TemplateException;
|
|||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
import org.libreccm.theming.manifest.DateFormat;
|
||||
import org.libreccm.theming.manifest.ThemeManifest;
|
||||
import org.libreccm.theming.manifest.ThemeManifestUtil;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
|
@ -34,13 +35,15 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Optional;
|
||||
import java.util.PropertyResourceBundle;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
|
@ -213,6 +216,11 @@ public class FreeMarkerPresentationManager implements PresentationManager {
|
|||
themePath,
|
||||
selectedLocale.getLanguage()));
|
||||
|
||||
configuration.setSharedVariable(
|
||||
"_formatDateTime",
|
||||
new FormatDateTime(manifest.getDateFormats(),
|
||||
new Locale(selectedLocale.getLanguage())));
|
||||
|
||||
data.put("serverName", request.getServerName());
|
||||
data.put("serverPort", request.getServerPort());
|
||||
data.put("userAgent", request.getHeader("user-Agent"));
|
||||
|
|
@ -430,44 +438,90 @@ public class FreeMarkerPresentationManager implements PresentationManager {
|
|||
|
||||
}
|
||||
|
||||
private class FormatDateTime implements TemplateMethodModelEx {
|
||||
|
||||
private final List<DateFormat> dateFormats;
|
||||
private final Locale locale;
|
||||
|
||||
public FormatDateTime(final List<DateFormat> dateFormats,
|
||||
final Locale locale) {
|
||||
|
||||
this.dateFormats = dateFormats;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object exec(final List list) throws TemplateModelException {
|
||||
|
||||
if (list.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"FormatDateTime requires the following parameters: "
|
||||
+ "style: string, year: int, month: int, "
|
||||
+ "day of month: int, hour: int, minute: int,"
|
||||
+ "second: int");
|
||||
}
|
||||
|
||||
final String style = ((TemplateScalarModel) list.get(0))
|
||||
.getAsString();
|
||||
final String yearParam = ((TemplateScalarModel) list.get(1))
|
||||
.getAsString();
|
||||
final String monthParam = ((TemplateScalarModel) list.get(2))
|
||||
.getAsString();
|
||||
final String dayOfMonthParam = ((TemplateScalarModel) list.get(3))
|
||||
.getAsString();
|
||||
final String hourParam = ((TemplateScalarModel) list.get(4))
|
||||
.getAsString();
|
||||
final String minuteParam = ((TemplateScalarModel) list.get(5))
|
||||
.getAsString();
|
||||
final String secondParam = ((TemplateScalarModel) list.get(6))
|
||||
.getAsString();
|
||||
|
||||
final int year = Integer.parseInt(yearParam);
|
||||
final int month = Integer.parseInt(monthParam);
|
||||
final int dayOfMonth = Integer.parseInt(dayOfMonthParam);
|
||||
final int hour = Integer.parseInt(hourParam);
|
||||
final int minute = Integer.parseInt(minuteParam);
|
||||
final int second = Integer.parseInt(secondParam);
|
||||
|
||||
final String format = findFormat(dateFormats, style, locale)
|
||||
.orElse("YYYY-MM-dd");
|
||||
|
||||
final LocalDateTime localDateTime = LocalDateTime.of(year,
|
||||
month,
|
||||
dayOfMonth,
|
||||
hour,
|
||||
minute,
|
||||
second);
|
||||
final DateTimeFormatter formatter = DateTimeFormatter
|
||||
.ofPattern(format, locale);
|
||||
|
||||
return formatter.format(localDateTime);
|
||||
}
|
||||
|
||||
private Optional<String> findFormat(
|
||||
final List<DateFormat> dateFormats,
|
||||
final String style,
|
||||
final Locale locale) {
|
||||
|
||||
final Optional<String> format = dateFormats
|
||||
.stream()
|
||||
.filter(dateFormat -> dateFormat.getStyle().equals(style))
|
||||
.filter(dateFormat -> dateFormat.getLang().equals(locale
|
||||
.toString()))
|
||||
.map(DateFormat::getFormat)
|
||||
.findAny();
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String findContentItemTemplate(
|
||||
final Templates templates,
|
||||
final String objectType,
|
||||
final ContentItemViews view,
|
||||
final String style) throws TemplateModelException {
|
||||
|
||||
// final String nodeNamespace = itemModel.getNodeNamespace();
|
||||
// final String nodeName = itemModel.getNodeName();
|
||||
// final String contentType;
|
||||
// if ("http://www.arsdigita.com/cms/1.0".equals(nodeNamespace)
|
||||
// && "item".equals(nodeName)) {
|
||||
// contentType = ((TemplateScalarModel) itemModel
|
||||
// .get("objectType"))
|
||||
// .getAsString();
|
||||
// } else if ("http://ccm.redhat.com/navigation".equals(nodeNamespace)
|
||||
// && "item".equals(nodeName)) {
|
||||
// final TemplateModel objectTypeElems = itemModel
|
||||
// .get("attribute[@name='objectType']");
|
||||
// if (objectTypeElems instanceof TemplateSequenceModel) {
|
||||
// final TemplateModel objectTypeElem
|
||||
// = ((TemplateSequenceModel) objectTypeElems)
|
||||
// .get(0);
|
||||
// contentType = ((TemplateScalarModel) objectTypeElem)
|
||||
// .getAsString();
|
||||
// } else if (objectTypeElems instanceof TemplateScalarModel) {
|
||||
// contentType = ((TemplateScalarModel) objectTypeElems)
|
||||
// .getAsString();
|
||||
// } else {
|
||||
// throw new IllegalArgumentException(
|
||||
// "Can't determine object type of item.");
|
||||
// }
|
||||
// } else {
|
||||
// throw new IllegalArgumentException(String.format(
|
||||
// "Unexpected combination of node namespace and nodename. "
|
||||
// + "nodeNamespace = \"%s\"; nodeName = \"%s\"",
|
||||
// nodeNamespace,
|
||||
// nodeName));
|
||||
// }
|
||||
final Optional<ContentItemTemplate> forTypeViewAndStyle = templates
|
||||
.getContentItems()
|
||||
.stream()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.libreccm.theming.manifest;
|
||||
|
||||
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 static org.libreccm.theming.ThemeConstants.*;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@XmlRootElement(name = "dateformat", namespace = THEMES_XML_NS)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class DateFormat {
|
||||
|
||||
@XmlElement(name = "style", namespace = THEMES_XML_NS)
|
||||
private String style;
|
||||
|
||||
@XmlElement(name = "lang", namespace = THEMES_XML_NS)
|
||||
private String lang;
|
||||
|
||||
@XmlElement(name = "format", namespace = THEMES_XML_NS)
|
||||
private String format;
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public void setLang(String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
public String getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public void setStyle(String style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 17 * hash + Objects.hashCode(lang);
|
||||
hash = 17 * hash + Objects.hashCode(style);
|
||||
hash = 17 * hash + Objects.hashCode(format);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof DateFormat)) {
|
||||
return false;
|
||||
}
|
||||
final DateFormat other = (DateFormat) obj;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(lang, other.getLang())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(style, other.getStyle())) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(format, other.getFormat());
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
|
||||
return obj instanceof DateFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
|
||||
return toString("");
|
||||
}
|
||||
|
||||
public String toString(final String data) {
|
||||
|
||||
return String.format("%s{ "
|
||||
+ "style = \"%s\", "
|
||||
+ "lang = \"%s\", "
|
||||
+ "format = \"%s\"%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
style,
|
||||
lang,
|
||||
format,
|
||||
data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,8 +31,11 @@ import javax.xml.bind.annotation.XmlRootElement;
|
|||
import static org.libreccm.theming.ThemeConstants.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
|
@ -90,12 +93,16 @@ public class ThemeManifest implements Serializable {
|
|||
@XmlElement(name = "default-template", namespace = THEMES_XML_NS)
|
||||
private String defaultTemplate;
|
||||
|
||||
@XmlElementWrapper(name = "config", namespace = THEMES_XML_NS)
|
||||
private Map<String, String> config;
|
||||
|
||||
@XmlElementWrapper(name = "date-time-formats", namespace = THEMES_XML_NS)
|
||||
@XmlElement(name = "date-time-formats", namespace = THEMES_XML_NS)
|
||||
private List<DateFormat> dateFormats;
|
||||
|
||||
public ThemeManifest() {
|
||||
// templates = new ArrayList<>();
|
||||
config = new HashMap<>();
|
||||
dateFormats = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -171,6 +178,26 @@ public class ThemeManifest implements Serializable {
|
|||
config.remove(key);
|
||||
}
|
||||
|
||||
public List<DateFormat> getDateFormats() {
|
||||
return Collections.unmodifiableList(dateFormats);
|
||||
}
|
||||
|
||||
public void setDateFormats(
|
||||
final ArrayList<DateFormat> dateFormats) {
|
||||
|
||||
this.dateFormats = new ArrayList<>(dateFormats);
|
||||
}
|
||||
|
||||
public void addDateFormat(final DateFormat dateFormat) {
|
||||
|
||||
dateFormats.add(dateFormat);
|
||||
}
|
||||
|
||||
public void removeDateFormat(final DateFormat dateFormat) {
|
||||
|
||||
dateFormats.remove(dateFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
|
|
|
|||
|
|
@ -38,3 +38,7 @@
|
|||
<#return false>
|
||||
</#if>
|
||||
</#function>
|
||||
|
||||
<#function formatDateTime style date>
|
||||
<#return _formatDateTime(style, date["./@year"], date["./@month"], date["./@day"], date["./@hour"], date["./@minute"], date["./@second"])>
|
||||
</#function>
|
||||
Loading…
Reference in New Issue