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:
rjy7 2010-05-21 15:55:26 +00:00
parent b9dfa9023b
commit bda278e59b
13 changed files with 138 additions and 56 deletions

View file

@ -82,7 +82,6 @@ public class BrowseController extends FreeMarkerHttpServlet {
String message = "";
List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), vreq.getPortal().getPortalId());
if (groups == null || groups.isEmpty()) {
message = "There are not yet any items in the system.";
body.put("message", message);

View file

@ -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.VitroRequest;
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.web.BreadCrumbsUtil;
import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
@ -137,34 +140,9 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
protected String mergeBodyToTemplate(String templateName, Map<String, Object> map) {
templateName = "body/" + templateName;
String body = mergeToTemplate(templateName, map).toString();
extractLinkTagsFromBody(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) {
String templateName = "page/default.ftl";
@ -218,17 +196,20 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
root.put("tagline", portal.getShortHand());
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(vreq));
String themeDir = portal.getThemeDir();
String themeDir = getThemeDir();
setUrls(portalId, themeDir);
setLoginInfo();
setCopyrightInfo();
setThemeInfo(themeDir);
// *** TEMPORARY. The templates shouldn't need to know this. Doing temporarily for script files
// till we put the script/css loading strategy in place. (Templates make a call to add files
// to a view object. These get iterated through in scripts.ftl and stylesheets.ftl.)
setSharedVariable("contextPath", contextPath);
// Here themeDir SHOULD NOT have the context path already added to it.
setSharedVariable("stylesheets", new StylesheetList(themeDir));
setSharedVariable("scripts", new ScriptList());
}
public String getThemeDir() {
return portal.getThemeDir().replaceAll("/$", "");
}
// 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("siteAdmin", getUrl(Routes.SITE_ADMIN));
System.out.println("LOGOUT: " + urls.get("logout"));
setSharedVariable("urls", urls);
}
@ -310,13 +291,14 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
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
// 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");
}
@ -325,10 +307,10 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
// 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.
// 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() {
String themeTemplateDir = context.getRealPath(portal.getThemeDir()) + "/ftl";
String themeTemplateDir = context.getRealPath(getThemeDir()) + "/ftl";
String vitroTemplateDir = context.getRealPath("/templates/freemarker");
try {

View file

@ -32,7 +32,7 @@ public class VClassView extends ViewObject {
return getUrl(URL, params);
}
public int getEntityCount() {
public int getIndividualCount() {
return vclass.getEntityCount();
}

View file

@ -10,7 +10,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet;
// 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 {

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -11,4 +11,3 @@
<#if acknowledgeText??>
<div class="pageGroupBody" id="acknowledgementText">${acknowledgeText}</div>
</#if>

View file

@ -10,7 +10,8 @@
<h2>${classGroup.publicName}</h2>
<ul>
<#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>
</ul>
</#list>

View file

@ -27,7 +27,7 @@
</p>
</#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="RequiredFields" value="webusername,webuseremail,s34gfd88p9x1"/>
<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>
<label>Your comments, questions, or suggestions</label>
<label>Comments, questions, or suggestions</label>
<textarea name="s34gfd88p9x1" rows="10" cols="90"></textarea>
<div>
<div class="buttons">
<input type="submit" value="Send Mail" class="yellowbutton"/>
<input type="reset" value="Clear Form" class="plainbutton"/>
</div
@ -55,5 +55,6 @@
</div>
<#-- RY This is temporary. -->
<script src="${contextPath}/js/commentForm.js"></script>
<#-- RY This is temporary.
<script src="${contextPath}/js/commentForm.js"></script>-->
${scripts.add("/js/commentForm.js")}

View file

@ -1,5 +1,6 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
${scripts.tags}
<#include "googleAnalytics.ftl">
<#-- OTHER SCRIPT TAGS HERE -->

View file

@ -1,10 +1,6 @@
<#-- $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}print.css" media="print"/>
<link rel="stylesheet" type="text/css" href="${stylesheetDir}/screen.css" media="screen"/>
<link rel="stylesheet" type="text/css" href="${stylesheetDir}/print.css" media="print"/>
<#if stylesheeets??>
<#list stylesheets as stylesheet>
${stylesheet}
</#list>
</#if>
${stylesheets.tags}

View file

@ -36,3 +36,10 @@
<#include "/components/scripts.ftl">
</body>
</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")}
-->