Implement multi-location template loading to look for a template first in the themes directory, then in the vitro template directory.
This commit is contained in:
parent
a0c93fda6d
commit
7c72f0f37c
4 changed files with 55 additions and 29 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
@ -13,6 +14,7 @@ import java.util.Map;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -27,6 +29,11 @@ import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
|||
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.view.menu.TabMenu;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil;
|
||||
|
||||
import freemarker.cache.ClassTemplateLoader;
|
||||
import freemarker.cache.FileTemplateLoader;
|
||||
import freemarker.cache.MultiTemplateLoader;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
@ -34,11 +41,12 @@ import freemarker.template.TemplateModelException;
|
|||
|
||||
public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||
|
||||
private static final Log log = LogFactory.getLog(FreeMarkerHttpServlet.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log log = LogFactory.getLog(FreeMarkerHttpServlet.class.getName());
|
||||
private static final int FILTER_SECURITY_LEVEL = LoginFormBean.EDITOR;
|
||||
|
||||
public static Configuration config = null;
|
||||
public static String contextPath = null; // RY or do we need to store the entire ServletContext?
|
||||
public static String contextPath = null;
|
||||
|
||||
protected VitroRequest vreq;
|
||||
protected HttpServletResponse response;
|
||||
|
@ -50,6 +58,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
// a getBody() and getTitle() method and use the parent doGet() method.
|
||||
public void doGet( HttpServletRequest request, HttpServletResponse response )
|
||||
throws IOException, ServletException {
|
||||
|
||||
try {
|
||||
doSetup(request, response);
|
||||
setTitle();
|
||||
|
@ -161,19 +170,19 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
protected void doSetup(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
try {
|
||||
super.doGet(request,response);
|
||||
} catch (ServletException e1) {
|
||||
super.doGet(request,response);
|
||||
} catch (ServletException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
} catch (IOException e1) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
vreq = new VitroRequest(request);
|
||||
this.response = response;
|
||||
portal = vreq.getPortal();
|
||||
|
||||
portal = vreq.getPortal();
|
||||
|
||||
// RY Can this be removed? Do templates need it? Ideally, they should not.
|
||||
// Only needed for some weird stuff in search box that I think is only used in old default theme.
|
||||
int portalId = portal.getPortalId();
|
||||
|
@ -183,6 +192,8 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
log.error("Can't set shared variable 'portalId'.");
|
||||
}
|
||||
|
||||
setTemplateLoader();
|
||||
|
||||
TabMenu menu = getTabMenu(portalId);
|
||||
root.put("tabMenu", menu);
|
||||
|
||||
|
@ -226,7 +237,6 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
urls.put("about", getUrl(Controllers.ABOUT + "?home=" + portalId));
|
||||
urls.put("aboutFM", getUrl(Controllers.ABOUT + "-fm?home=" + portalId)); // TEMPORARY
|
||||
if (ContactMailServlet.getSmtpHostFromProperties() != null) {
|
||||
urls.put("contact", getUrl(Controllers.CONTACT_URL + "?home=" + portalId));
|
||||
}
|
||||
|
@ -277,6 +287,32 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
root.put("copyright", copyright);
|
||||
}
|
||||
}
|
||||
|
||||
// Define template locations. Template loader will look first in the theme-specific
|
||||
// location, then in the vitro location.
|
||||
// RY We cannot do this in FreeMarkerSetup because (a) the theme depends on the portal,
|
||||
// and we have multi-portal installations, and (b) we need to support theme-switching on the fly.
|
||||
// To make more efficient, we could do this once, and then have a listener that does it again
|
||||
// when theme is switched.BUT this doesn't support (a), only (b), so we have to do it on every request.
|
||||
private final void setTemplateLoader() {
|
||||
|
||||
// RY If this is needed in other methods, put in instance var
|
||||
ServletContext context = getServletContext();
|
||||
String themeTemplateDir = context.getRealPath(portal.getThemeDir()) + "/ftl";
|
||||
String vitroTemplateDir = context.getRealPath("/templates/freemarker");
|
||||
|
||||
try {
|
||||
FileTemplateLoader themeFtl = new FileTemplateLoader(new File(themeTemplateDir));
|
||||
FileTemplateLoader vitroFtl = new FileTemplateLoader(new File(vitroTemplateDir));
|
||||
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
|
||||
TemplateLoader[] loaders = new TemplateLoader[] { themeFtl, vitroFtl, ctl };
|
||||
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
|
||||
config.setTemplateLoader(mtl);
|
||||
} catch (IOException e) {
|
||||
log.error("Error loading templates");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String getUrl(String path) {
|
||||
if ( ! path.startsWith("/") ) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.FreeMarkerHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.view.ViewObject;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.DefaultObjectWrapper;
|
||||
import freemarker.template.TemplateException;
|
||||
|
@ -27,24 +28,14 @@ public class FreeMarkerSetup implements ServletContextListener {
|
|||
|
||||
ServletContext sc = event.getServletContext();
|
||||
|
||||
// RY Change this to multi-location template scheme
|
||||
String templatePath = sc.getRealPath("/templates/freemarker");
|
||||
|
||||
Configuration cfg = new Configuration();
|
||||
|
||||
/* **** RY
|
||||
Here's what I want to do to avoid having to pass in the contextPath to every view object created (in order for them to create their URLs):
|
||||
Subclass Configuration. Add a static variable CONTEXT_PATH to it. Set that value here, and define a getter also. Then when creating
|
||||
urls in view object methods like getUrl(), we can reference that configuration value. None of this is possible unless we can use
|
||||
the method ServletContext.getContextPath(), new to Servlet API 2.5 andn therefore requiring tomcat 6 rather than 5.
|
||||
*/
|
||||
|
||||
// Specify the data source where the template files come from.
|
||||
try {
|
||||
cfg.setDirectoryForTemplateLoading(new File(templatePath));
|
||||
} catch (IOException e) {
|
||||
log.error("Error specifying template directory.");
|
||||
}
|
||||
// try {
|
||||
// cfg.setDirectoryForTemplateLoading(new File(templatePath));
|
||||
// } catch (IOException e) {
|
||||
// log.error("Error specifying template directory.");
|
||||
// }
|
||||
|
||||
// RY This setting won't take effect until we use Configuration.getTemplate() to
|
||||
// create templates.
|
||||
|
@ -69,6 +60,7 @@ public class FreeMarkerSetup implements ServletContextListener {
|
|||
String contextPath = sc.getContextPath();
|
||||
FreeMarkerHttpServlet.contextPath = contextPath;
|
||||
ViewObject.contextPath = contextPath;
|
||||
|
||||
}
|
||||
|
||||
public void contextDestroyed(ServletContextEvent event) {
|
||||
|
|
|
@ -44,8 +44,7 @@ public class TabMenu extends MainMenu {
|
|||
// Hard-coded tabs. It's not really a good idea to have these here, since any menu item that doesn't
|
||||
// come from the db should be accessible to the template to change the text. But we need them here
|
||||
// to apply the "active" mechanism.
|
||||
addItem("Index", "/browsecontroller");
|
||||
addItem("Index - FM", "/browse");
|
||||
addItem("Index", "/browsecontroller");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
</#if>
|
||||
|
||||
<li><a href="${urls.about}$">About</a></li>,
|
||||
<li><a href="${urls.aboutFM}">About - FM</a></li>,
|
||||
<#if urls.contact??>
|
||||
<li><a href="${urls.contact}">Contact Us</a></li>
|
||||
</#if>
|
||||
|
|
Loading…
Add table
Reference in a new issue