Implement StylesheetList and ScriptList view objects and new strategy for templates to direct stylesheets and script files to be loaded onto a page.
This commit is contained in:
parent
b9dfa9023b
commit
bda278e59b
13 changed files with 138 additions and 56 deletions
|
@ -82,7 +82,6 @@ public class BrowseController extends FreeMarkerHttpServlet {
|
||||||
|
|
||||||
String message = "";
|
String message = "";
|
||||||
List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), vreq.getPortal().getPortalId());
|
List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), vreq.getPortal().getPortalId());
|
||||||
|
|
||||||
if (groups == null || groups.isEmpty()) {
|
if (groups == null || groups.isEmpty()) {
|
||||||
message = "There are not yet any items in the system.";
|
message = "There are not yet any items in the system.";
|
||||||
body.put("message", message);
|
body.put("message", message);
|
||||||
|
|
|
@ -34,9 +34,12 @@ import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.view.fileList.ScriptList;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.view.fileList.StylesheetList;
|
||||||
import edu.cornell.mannlib.vitro.webapp.view.menu.TabMenu;
|
import edu.cornell.mannlib.vitro.webapp.view.menu.TabMenu;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.BreadCrumbsUtil;
|
import edu.cornell.mannlib.vitro.webapp.web.BreadCrumbsUtil;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil;
|
import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil;
|
||||||
|
|
||||||
import freemarker.cache.ClassTemplateLoader;
|
import freemarker.cache.ClassTemplateLoader;
|
||||||
import freemarker.cache.FileTemplateLoader;
|
import freemarker.cache.FileTemplateLoader;
|
||||||
import freemarker.cache.MultiTemplateLoader;
|
import freemarker.cache.MultiTemplateLoader;
|
||||||
|
@ -67,7 +70,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
// a getBody() and getTitle() method and use the parent doGet() method.
|
// a getBody() and getTitle() method and use the parent doGet() method.
|
||||||
public void doGet( HttpServletRequest request, HttpServletResponse response )
|
public void doGet( HttpServletRequest request, HttpServletResponse response )
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
callSuperGet(request, response); // ??
|
callSuperGet(request, response); // ??
|
||||||
doSetup(request, response);
|
doSetup(request, response);
|
||||||
|
@ -137,33 +140,8 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
protected String mergeBodyToTemplate(String templateName, Map<String, Object> map) {
|
protected String mergeBodyToTemplate(String templateName, Map<String, Object> map) {
|
||||||
templateName = "body/" + templateName;
|
templateName = "body/" + templateName;
|
||||||
String body = mergeToTemplate(templateName, map).toString();
|
String body = mergeToTemplate(templateName, map).toString();
|
||||||
extractLinkTagsFromBody(body);
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the only way to do this in FreeMarker. We cannot: (1) put a sequence of stylesheets in the template
|
|
||||||
// context which the template can add to, because the template cannot call methods on the container. The template
|
|
||||||
// can create a container but not add to one.
|
|
||||||
// (2) create a sequence of stylesheets or a scalar to hold the name of a stylesheet in the template, because
|
|
||||||
// it does not get passed back to the controller. The template can create only local variables.
|
|
||||||
|
|
||||||
// *** RY But we can create a view object with an add method, that the templates could use to add to the
|
|
||||||
// list. ***
|
|
||||||
private String extractLinkTagsFromBody(String body) {
|
|
||||||
List<String> links = new ArrayList<String>();
|
|
||||||
|
|
||||||
String re = "<link[^>]*>";
|
|
||||||
Pattern pattern = Pattern.compile(re);
|
|
||||||
Matcher matcher = pattern.matcher(body);
|
|
||||||
while (matcher.find()) {
|
|
||||||
links.add(matcher.group());
|
|
||||||
}
|
|
||||||
|
|
||||||
root.put("stylesheets", links); // SIDE-EFFECT
|
|
||||||
|
|
||||||
body = matcher.replaceAll("");
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void write(HttpServletResponse response) {
|
protected void write(HttpServletResponse response) {
|
||||||
|
|
||||||
|
@ -218,17 +196,20 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
root.put("tagline", portal.getShortHand());
|
root.put("tagline", portal.getShortHand());
|
||||||
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(vreq));
|
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(vreq));
|
||||||
|
|
||||||
String themeDir = portal.getThemeDir();
|
String themeDir = getThemeDir();
|
||||||
|
|
||||||
setUrls(portalId, themeDir);
|
setUrls(portalId, themeDir);
|
||||||
setLoginInfo();
|
setLoginInfo();
|
||||||
setCopyrightInfo();
|
setCopyrightInfo();
|
||||||
setThemeInfo(themeDir);
|
setThemeInfo(themeDir);
|
||||||
|
|
||||||
// *** TEMPORARY. The templates shouldn't need to know this. Doing temporarily for script files
|
// Here themeDir SHOULD NOT have the context path already added to it.
|
||||||
// till we put the script/css loading strategy in place. (Templates make a call to add files
|
setSharedVariable("stylesheets", new StylesheetList(themeDir));
|
||||||
// to a view object. These get iterated through in scripts.ftl and stylesheets.ftl.)
|
setSharedVariable("scripts", new ScriptList());
|
||||||
setSharedVariable("contextPath", contextPath);
|
}
|
||||||
|
|
||||||
|
public String getThemeDir() {
|
||||||
|
return portal.getThemeDir().replaceAll("/$", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the URLs that are accessible to the templates. Note that we do not create menus here,
|
// Define the URLs that are accessible to the templates. Note that we do not create menus here,
|
||||||
|
@ -265,7 +246,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
urls.put("logout", getUrl(Routes.LOGOUT, logoutParams));
|
urls.put("logout", getUrl(Routes.LOGOUT, logoutParams));
|
||||||
|
|
||||||
urls.put("siteAdmin", getUrl(Routes.SITE_ADMIN));
|
urls.put("siteAdmin", getUrl(Routes.SITE_ADMIN));
|
||||||
System.out.println("LOGOUT: " + urls.get("logout"));
|
|
||||||
setSharedVariable("urls", urls);
|
setSharedVariable("urls", urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,14 +291,15 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
|
|
||||||
private final void setThemeInfo(String themeDir) {
|
private final void setThemeInfo(String themeDir) {
|
||||||
|
|
||||||
setSharedVariable("themeDir", getUrl(themeDir));
|
themeDir = getUrl(themeDir);
|
||||||
|
setSharedVariable("themeDir", themeDir);
|
||||||
|
|
||||||
// We'll need to separate theme-general and theme-specific stylesheet
|
// We'll need to separate theme-general and theme-specific stylesheet
|
||||||
// dirs, so we need either two attributes or a list.
|
// dirs, so we need either two attributes or a list.
|
||||||
setSharedVariable("stylesheetDir", getUrl(themeDir + "css/"));
|
setSharedVariable("stylesheetDir", themeDir + "/css");
|
||||||
|
|
||||||
setSharedVariable("siteIconDir", getUrl(themeDir + "site_icons/"));
|
|
||||||
|
|
||||||
|
setSharedVariable("siteIconDir", themeDir + "/site_icons");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define template locations. Template loader will look first in the theme-specific
|
// Define template locations. Template loader will look first in the theme-specific
|
||||||
|
@ -325,10 +307,10 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
// RY We cannot do this in FreeMarkerSetup because (a) the theme depends on the portal,
|
// 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.
|
// 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
|
// 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.
|
// when theme is switched. BUT this doesn't support (a), only (b), so we have to do it on every request.
|
||||||
protected final void setTemplateLoader() {
|
protected final void setTemplateLoader() {
|
||||||
|
|
||||||
String themeTemplateDir = context.getRealPath(portal.getThemeDir()) + "/ftl";
|
String themeTemplateDir = context.getRealPath(getThemeDir()) + "/ftl";
|
||||||
String vitroTemplateDir = context.getRealPath("/templates/freemarker");
|
String vitroTemplateDir = context.getRealPath("/templates/freemarker");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class VClassView extends ViewObject {
|
||||||
return getUrl(URL, params);
|
return getUrl(URL, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEntityCount() {
|
public int getIndividualCount() {
|
||||||
return vclass.getEntityCount();
|
return vclass.getEntityCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet;
|
||||||
|
|
||||||
// RY We may want an interface that the superclass would implement.
|
// RY We may want an interface that the superclass would implement.
|
||||||
// RY Consider using FreeMarker's DisplayObjectWrapper instead, or extending it.
|
// RY Consider using FreeMarker's object wrappers instead.
|
||||||
|
|
||||||
public abstract class ViewObject {
|
public abstract class ViewObject {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.view.fileList;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.view.ViewObject;
|
||||||
|
|
||||||
|
public abstract class FileList extends ViewObject {
|
||||||
|
|
||||||
|
protected List<String> list = null;
|
||||||
|
private String themeDir = null;
|
||||||
|
|
||||||
|
public FileList() {
|
||||||
|
this.list = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileList(String themeDir) {
|
||||||
|
this();
|
||||||
|
this.themeDir = themeDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileList(List<String> list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(String path) {
|
||||||
|
list.add(getUrl(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFromTheme(String path) {
|
||||||
|
path = themeDir + getThemeSubDir() + path;
|
||||||
|
add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTags() {
|
||||||
|
String tags = "";
|
||||||
|
|
||||||
|
Iterator<String> i = list.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
tags += getTag(i.next());
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String getThemeSubDir();
|
||||||
|
protected abstract String getTag(String url);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.view.fileList;
|
||||||
|
|
||||||
|
public class ScriptList extends FileList {
|
||||||
|
|
||||||
|
protected static final String THEME_SUBDIR = "/js";
|
||||||
|
|
||||||
|
public ScriptList() { }
|
||||||
|
|
||||||
|
public ScriptList(String themeDir) {
|
||||||
|
super(themeDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getTag(String url) {
|
||||||
|
return "<script type=\"text/javascript\" src=\"" + url + "\"></script>";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getThemeSubDir() {
|
||||||
|
return THEME_SUBDIR;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.view.fileList;
|
||||||
|
|
||||||
|
public class StylesheetList extends FileList {
|
||||||
|
|
||||||
|
protected static final String THEME_SUBDIR = "/css";
|
||||||
|
|
||||||
|
public StylesheetList() { }
|
||||||
|
|
||||||
|
public StylesheetList(String themeDir) {
|
||||||
|
super(themeDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getTag(String url) {
|
||||||
|
return "<link rel=\"stylesheet\" href=\"" + url + "\" />";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getThemeSubDir() {
|
||||||
|
return THEME_SUBDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,4 +11,3 @@
|
||||||
<#if acknowledgeText??>
|
<#if acknowledgeText??>
|
||||||
<div class="pageGroupBody" id="acknowledgementText">${acknowledgeText}</div>
|
<div class="pageGroupBody" id="acknowledgementText">${acknowledgeText}</div>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
<h2>${classGroup.publicName}</h2>
|
<h2>${classGroup.publicName}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<#list classGroup.classes as class>
|
<#list classGroup.classes as class>
|
||||||
<li><a href="${class.url}">${class.name}</a> (${class.entityCount})</li>
|
<li><a href="${class.url}">${class.name}</a> (${class.individualCount})</li>
|
||||||
|
|
||||||
</#list>
|
</#list>
|
||||||
</ul>
|
</ul>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
</p>
|
</p>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<form name="contact_form" action="submitFeedback" method="post" onsubmit="return ValidateForm('contact_form');">
|
<form name="contact_form" id="contact_form" action="submitFeedback" method="post" onsubmit="return ValidateForm('contact_form');">
|
||||||
<input type="hidden" name="home" value="${portalId}"/>
|
<input type="hidden" name="home" value="${portalId}"/>
|
||||||
<input type="hidden" name="RequiredFields" value="webusername,webuseremail,s34gfd88p9x1"/>
|
<input type="hidden" name="RequiredFields" value="webusername,webuseremail,s34gfd88p9x1"/>
|
||||||
<input type="hidden" name="RequiredFieldsNames" value="Name,Email address,Comments"/>
|
<input type="hidden" name="RequiredFieldsNames" value="Name,Email address,Comments"/>
|
||||||
|
@ -41,11 +41,11 @@
|
||||||
<p><input style="width:25%;" type="text" name="webuseremail" maxlength="255"/></p>
|
<p><input style="width:25%;" type="text" name="webuseremail" maxlength="255"/></p>
|
||||||
|
|
||||||
|
|
||||||
<label>Your comments, questions, or suggestions</label>
|
<label>Comments, questions, or suggestions</label>
|
||||||
|
|
||||||
<textarea name="s34gfd88p9x1" rows="10" cols="90"></textarea>
|
<textarea name="s34gfd88p9x1" rows="10" cols="90"></textarea>
|
||||||
|
|
||||||
<div>
|
<div class="buttons">
|
||||||
<input type="submit" value="Send Mail" class="yellowbutton"/>
|
<input type="submit" value="Send Mail" class="yellowbutton"/>
|
||||||
<input type="reset" value="Clear Form" class="plainbutton"/>
|
<input type="reset" value="Clear Form" class="plainbutton"/>
|
||||||
</div
|
</div
|
||||||
|
@ -55,5 +55,6 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<#-- RY This is temporary. -->
|
<#-- RY This is temporary.
|
||||||
<script src="${contextPath}/js/commentForm.js"></script>
|
<script src="${contextPath}/js/commentForm.js"></script>-->
|
||||||
|
${scripts.add("/js/commentForm.js")}
|
|
@ -1,5 +1,6 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
${scripts.tags}
|
||||||
|
|
||||||
<#include "googleAnalytics.ftl">
|
<#include "googleAnalytics.ftl">
|
||||||
|
|
||||||
<#-- OTHER SCRIPT TAGS HERE -->
|
|
|
@ -1,10 +1,6 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="${stylesheetDir}screen.css" media="screen"/>
|
<link rel="stylesheet" type="text/css" href="${stylesheetDir}/screen.css" media="screen"/>
|
||||||
<link rel="stylesheet" type="text/css" href="${stylesheetDir}print.css" media="print"/>
|
<link rel="stylesheet" type="text/css" href="${stylesheetDir}/print.css" media="print"/>
|
||||||
|
|
||||||
<#if stylesheeets??>
|
${stylesheets.tags}
|
||||||
<#list stylesheets as stylesheet>
|
|
||||||
${stylesheet}
|
|
||||||
</#list>
|
|
||||||
</#if>
|
|
|
@ -36,3 +36,10 @@
|
||||||
<#include "/components/scripts.ftl">
|
<#include "/components/scripts.ftl">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
<#-- How to add a stylesheet:
|
||||||
|
${stylesheets.addFromTheme("/sample.css");
|
||||||
|
${stylesheets.add("/themes/vivo-basic/css/sample.css"}
|
||||||
|
NOT (gets contextPath added twice):
|
||||||
|
${stylesheets.add(stylesheetDir + "/sample.css")}
|
||||||
|
-->
|
Loading…
Add table
Reference in a new issue