diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java index 34942ddc9..b9de38980 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java @@ -544,8 +544,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { } } - // This class is also used by WidgetDirective, so is public. - public static class TemplateResponseValues extends BaseResponseValues { + protected static class TemplateResponseValues extends BaseResponseValues { private final String templateName; private final Map map; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/WidgetDirective.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/WidgetDirective.java index 98891fd9f..2a967f341 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/WidgetDirective.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/WidgetDirective.java @@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.web.directives; import java.io.IOException; import java.io.Writer; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Map; @@ -12,7 +11,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; import edu.cornell.mannlib.vitro.webapp.web.widgets.Widget; import freemarker.core.Environment; @@ -65,22 +63,18 @@ public class WidgetDirective extends BaseTemplateDirectiveModel { try { String widgetClassName = WIDGET_PACKAGE + "." + StringUtils.capitalize(widgetName) + "Widget"; Class widgetClass = Class.forName(widgetClassName); - // Use Constructor.newInstance() rather than Class.newInstance() so we can pass arguments - // to the constructor. - // Widget widget = (Widget) widgetClass.newInstance(); - Constructor widgetConstructor = widgetClass.getConstructor(new Class[]{Environment.class, String.class}); - Widget widget = (Widget) widgetConstructor.newInstance(env, widgetName); - Method method = widgetClass.getMethod(methodName); + Widget widget = (Widget) widgetClass.newInstance(); + Method method = widgetClass.getMethod(methodName, Environment.class, Map.class); // Right now it seems to me that we will always be producing a string for the widget calls. If we need greater // flexibility, we can return a ResponseValues object and deal with different types here. - String output = (String) method.invoke(widget); - - String templateType = env.getDataModel().get("templateType").toString(); + String output = (String) method.invoke(widget, env, params); + // If we're in the body template, automatically invoke the doAssets() method, so it - // doesn't need to be called explicitly. + // doesn't need to be called explicitly from the enclosing template. + String templateType = env.getDataModel().get("templateType").toString(); if ("doMarkup".equals(methodName) && FreemarkerHttpServlet.BODY_TEMPLATE_TYPE.equals(templateType)) { - output += widgetClass.getMethod("doAssets").invoke(widget); + output += widgetClass.getMethod("doAssets", Environment.class, Map.class).invoke(widget, env, params); } Writer out = env.getOut(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java index d522c25a6..c8e0bbbf9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java @@ -5,25 +5,23 @@ package edu.cornell.mannlib.vitro.webapp.web.widgets; import java.util.HashMap; import java.util.Map; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet.TemplateResponseValues; import freemarker.core.Environment; public class LoginWidget extends Widget { private static final Log log = LogFactory.getLog(LoginWidget.class); - - public LoginWidget(Environment env, String name) { - super(env, name); - } @Override - protected TemplateResponseValues getTemplateResponseValues() { + protected WidgetTemplateValues process(Environment env, Map params, String widgetName, HttpServletRequest request, ServletContext context) { Map map = new HashMap(); map.put("fruit", "bananas"); - return new TemplateResponseValues (markupTemplateName(), map); + return new WidgetTemplateValues (getMarkupTemplateName(widgetName), map); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/TestWidget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/TestWidget.java index 4c5331c0b..614b31672 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/TestWidget.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/TestWidget.java @@ -5,20 +5,18 @@ package edu.cornell.mannlib.vitro.webapp.web.widgets; import java.util.HashMap; import java.util.Map; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet.TemplateResponseValues; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + import freemarker.core.Environment; public class TestWidget extends Widget { - public TestWidget(Environment env, String name) { - super(env, name); - } - @Override - protected TemplateResponseValues getTemplateResponseValues() { + protected WidgetTemplateValues process(Environment env, Map params, String widgetName, HttpServletRequest request, ServletContext context) { Map map = new HashMap(); map.put("fruit", "bananas"); - return new TemplateResponseValues (markupTemplateName(), map); + return new WidgetTemplateValues (getMarkupTemplateName(widgetName), map); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java index 50991a030..a0f415a38 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java @@ -3,6 +3,8 @@ package edu.cornell.mannlib.vitro.webapp.web.widgets; import java.io.IOException; +import java.io.StringWriter; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -12,11 +14,10 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet.TemplateResponseValues; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper; import freemarker.cache.TemplateLoader; import freemarker.core.Environment; import freemarker.template.Configuration; +import freemarker.template.Template; import freemarker.template.TemplateHashModel; import freemarker.template.TemplateModelException; @@ -24,31 +25,13 @@ public abstract class Widget { private static final Log log = LogFactory.getLog(Widget.class); - protected Environment env = null; - private TemplateProcessingHelper helper = null; - private String name = null; - -// protected TemplateDirectiveModel directive = null; -// protected Macro markupMacro = null; -// protected Macro assetsMacro = null; + /* Widget implementations don't get any state when they get constructed so that they + * can be reused. */ + public Widget() { } - public Widget(Environment env, String name) { - this.env = env; - this.name = name; - Configuration config = env.getConfiguration(); - HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request"); - ServletContext context = (ServletContext) env.getCustomAttribute("context"); - this.helper = new TemplateProcessingHelper(config, request, context); - - //this.directive = directive; - //Template template = getTemplate(); - //Map templateMacros = template.getMacros(); - //markupMacro = (Macro) templateMacros.get("markup"); - //assetsMacro = (Macro) templateMacros.get("assets"); - } - - public String doAssets() { - String templateName = assetsTemplateName(); + public String doAssets(Environment env, Map params) { + String widgetName = params.get("name").toString(); //getWidgetName(); + String templateName = getAssetsTemplateName(widgetName); // Allow the assets template to be absent without generating an error. TemplateLoader templateLoader = env.getConfiguration().getTemplateLoader(); @@ -71,29 +54,79 @@ public abstract class Widget { log.error("Error getting asset values from data model."); } - return helper.processTemplateToString(templateName, map); + return processTemplateToString(widgetName, env, templateName, map); + } + public String doMarkup(Environment env, Map params) { + HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request"); + ServletContext context = (ServletContext) env.getCustomAttribute("context"); + String widgetName = params.get("name").toString(); // getWidgetName(); + WidgetTemplateValues values = process(env, params, widgetName, request, context); + return processTemplateToString(widgetName, env, values); + } + // Default assets template name. Can be overridden by subclasses. - protected String assetsTemplateName() { - return "widget-" + name + "-assets.ftl"; + protected String getAssetsTemplateName(String widgetName) { + return "widget-" + widgetName + "-assets.ftl"; } - public String doMarkup() { - TemplateResponseValues values = getTemplateResponseValues(); - return helper.processTemplateToString(values); - } - // Default markup template name. Can be overridden in subclasses, or assigned - // differently in the subclass doMarkup() method. For example, LoginWidget will + // differently in the subclass process() method. For example, LoginWidget will // select a template according to login processing status. - protected String markupTemplateName() { - return "widget-" + name + "-markup.ftl"; + protected String getMarkupTemplateName(String widgetName) { + return "widget-" + widgetName + "-markup.ftl"; } - protected abstract TemplateResponseValues getTemplateResponseValues(); +// private String getWidgetName() { +// String name = this.getClass().getName(); +// name= name.replaceAll(".*\\.", ""); +// name = name.replaceAll("Widget$", ""); +// name = name.substring(0, 1).toLowerCase() + name.substring(1); +// return name; +// } + + protected abstract WidgetTemplateValues process(Environment env, Map params, String widgetName, HttpServletRequest request, ServletContext context); + + private String processTemplateToString(String widgetName, Environment env, String templateName, Map map) { + StringWriter out = new StringWriter(); + Configuration config = env.getConfiguration(); + try { + Template template = config.getTemplate(templateName); + template.process(map, out); + } catch (Throwable th) { + log.error("Could not process widget " + widgetName, th); + } + return out.toString(); + } + + private String processTemplateToString(String widgetName, Environment env, WidgetTemplateValues values) { + return processTemplateToString(widgetName, env, values.getTemplateName(), values.getMap()); + } + + + protected static class WidgetTemplateValues { + private final String templateName; + private final Map map; + + public WidgetTemplateValues(String templateName, Map map) { + this.templateName = templateName; + this.map = map; + } + + public WidgetTemplateValues put(String key, Object value) { + this.map.put(key, value); + return this; + } + + public Map getMap() { + return Collections.unmodifiableMap(this.map); + } + + public String getTemplateName() { + return this.templateName; + } + + } } - -//# You can capture the output of an arbitrary part of the template into a context variable. -//# You can interpret arbitrary context variable as if it were a template definition. \ No newline at end of file diff --git a/webapp/web/templates/freemarker/widgets/test/widget-test-markup.ftl b/webapp/web/templates/freemarker/widgets/test/widget-test-markup.ftl index 0bcfe10af..3e56da1b5 100644 --- a/webapp/web/templates/freemarker/widgets/test/widget-test-markup.ftl +++ b/webapp/web/templates/freemarker/widgets/test/widget-test-markup.ftl @@ -1,5 +1,6 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> -

This is the test widget.

- -

${fruit}

\ No newline at end of file +
+

This is the test widget.

+

I like ${fruit}.

+
\ No newline at end of file diff --git a/webapp/web/templates/freemarker/widgets/widget-test.ftl b/webapp/web/templates/freemarker/widgets/widget-test.ftl new file mode 100644 index 000000000..a9300ecbc --- /dev/null +++ b/webapp/web/templates/freemarker/widgets/widget-test.ftl @@ -0,0 +1,16 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Test widget --> + +<#macro assets> + ${stylesheets.add("/css/test.css")} + ${scripts.add("/js/testscript.js")} + ${headScripts.add("/js/testheadscript.js")} + + +<#macro markup> +
+

This is the test widget.

+

I like ${fruit}.

+
+ \ No newline at end of file