Rewrote comment form controllers and templates in FreeMarker.

This commit is contained in:
rjy7 2010-05-19 19:50:54 +00:00
parent ae01a03122
commit f88a77d307
24 changed files with 723 additions and 208 deletions

View file

@ -849,6 +849,17 @@
<url-pattern>/contact</url-pattern>
</servlet-mapping>
<!-- TEMPORARY - for comparison with new version -->
<servlet>
<servlet-name>CommentsController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.CommentsController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CommentsController</servlet-name>
<url-pattern>/comments-old</url-pattern>
</servlet-mapping>
<!-- end TEMPORARY -->
<servlet>
<servlet-name>JSON Service</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.JSONServlet</servlet-class>
@ -924,11 +935,27 @@
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<!-- Deprecated servlet (still used in Datastar) - retain temporarily for testing and comparison. -->
<servlet>
<servlet-name>sendmail</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet</servlet-class>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>sendmail</servlet-name>
<url-pattern>/sendmail</url-pattern>
</servlet-mapping>
<!-- end deprecated servlet -->
<servlet>
<servlet-name>sendMail</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ContactMailController</servlet-class>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>sendMail</servlet-name>
<url-pattern>/sendMail</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mailusers</servlet-name>
@ -1046,10 +1073,6 @@
<servlet-mapping>
<servlet-name>fetch</servlet-name>
<url-pattern>/fetch</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>sendmail</servlet-name>
<url-pattern>/sendmail</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>mailusers</servlet-name>

View file

@ -57,7 +57,7 @@ public class CommentsController extends VitroHttpServlet{
}
request.setAttribute("siteName",portalBean.getAppName());
request.setAttribute("scripts","/js/commentsForm.js");
request.setAttribute("scripts","/js/commentsForm.jsp");
if (request.getHeader("Referer") == null)
request.getSession().setAttribute("commentsFormReferer","none");

View file

@ -24,8 +24,8 @@ public class AboutController extends FreeMarkerHttpServlet {
body.put("aboutText", portal.getAboutText());
body.put("acknowledgeText", portal.getAcknowledgeText());
String templateName = "body/about.ftl";
return mergeBodyToTemplate(templateName, body);
String bodyTemplate = "about.ftl";
return mergeBodyToTemplate(bodyTemplate, body);
}

View file

@ -72,7 +72,8 @@ public class BrowseController extends FreeMarkerHttpServlet {
Map body = new HashMap();
// Set main page template attributes specific to this page
root.put("contentClass", "siteMap");
// But the template should control this! Try putting in a div inside the content.
//root.put("contentClass", "siteMap");
if( vreq.getParameter("clearcache") != null ) //mainly for debugging
clearGroupCache();
@ -99,8 +100,8 @@ public class BrowseController extends FreeMarkerHttpServlet {
body.put("classGroups", vcgroups);
}
String templateName = "body/classGroups.ftl";
return mergeBodyToTemplate(templateName, body);
String bodyTemplate = "classGroups.ftl";
return mergeBodyToTemplate(bodyTemplate, body);
}
public void destroy(){

View file

@ -3,87 +3,85 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
/**
* Controller for comments ("contact us") page
* * @author bjl23
*/
public class CommentFormController extends FreeMarkerHttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public void doGet( HttpServletRequest request, HttpServletResponse response )
throws IOException, ServletException {
super.doGet(request,response);
VitroRequest vreq = new VitroRequest(request);
try {
//this try block passes any errors to error.jsp
if (!ContactMailServlet.isSmtpHostConfigured()) {
request.setAttribute("title", "Comments and Feedback Form");
request.setAttribute("bodyJsp", "/contact_err.jsp");// <<< this is where the body gets set
request.setAttribute("ERR","This application has not yet been configured to send mail -- " +
"smtp host has not been specified in the configuration properties file.");
RequestDispatcher errd = request.getRequestDispatcher(Controllers.BASIC_JSP);
errd.forward(request, response);
}
ApplicationBean appBean=vreq.getAppBean();
Portal portalBean=vreq.getPortal();
if ( (appBean.getMaxSharedPortalId()-appBean.getMinSharedPortalId()) > 1
&& ( (portalBean.getPortalId() >= appBean.getMinSharedPortalId()
&& portalBean.getPortalId() <= appBean.getMaxSharedPortalId() )
|| portalBean.getPortalId() == appBean.getSharedPortalFlagNumeric() )
) {
request.setAttribute("portalType","CALSResearch");
} else
if (portalBean.getAppName().equalsIgnoreCase("CALS Impact")){
request.setAttribute("portalType", "CALSImpact");
} else if (portalBean.getAppName().equalsIgnoreCase("VIVO")) {
request.setAttribute("portalType", "VIVO");
} else {
request.setAttribute("portalType", "clone");
}
request.setAttribute("siteName",portalBean.getAppName());
request.setAttribute("scripts","/js/commentsForm.js");
if (request.getHeader("Referer") == null)
request.getSession().setAttribute("commentsFormReferer","none");
else
request.getSession().setAttribute("commentsFormReferer",request.getHeader("Referer"));
request.setAttribute("portalId",Integer.valueOf(portalBean.getPortalId()));
request.setAttribute("title", portalBean.getAppName()+" Comments and Feedback Form");
request.setAttribute("bodyJsp", "/commentsForm.jsp");// <<< this is where the body gets set
request.setAttribute("portalBean",portalBean);
RequestDispatcher rd =
request.getRequestDispatcher(Controllers.BASIC_JSP);
rd.forward(request, response);
} catch (Throwable e) {
// This is how we use an error.jsp
//it expects javax.servlet.jsp.jspException to be set to the
//exception so that it can display the info out of that.
request.setAttribute("javax.servlet.jsp.jspException", e);
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
rd.include(request, response);
}
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(CommentFormController.class.getName());
protected String getTitle() {
return appName + " Feedback Form";
}
protected String getBody() {
Map<String, Object> body = new HashMap<String, Object>();
String bodyTemplate;
if (!ContactMailServlet.isSmtpHostConfigured()) {
body.put("errorMessage",
"This application has not yet been configured to send mail. " +
"An smtp host has not been specified in the configuration properties file.");
bodyTemplate = "commentForm/error.ftl";
}
else if (StringUtils.isEmpty(portal.getContactMail())) {
body.put("errorMessage",
"The site administrator has not configured an email address to receive the form submission.");
bodyTemplate = "commentForm/error.ftl";
}
else {
ApplicationBean appBean = vreq.getAppBean();
int portalId = portal.getPortalId();
String portalType = null;
if ( (appBean.getMaxSharedPortalId()-appBean.getMinSharedPortalId()) > 1
&& ( (portalId >= appBean.getMinSharedPortalId()
&& portalId <= appBean.getMaxSharedPortalId() )
|| portalId == appBean.getSharedPortalFlagNumeric() ) ) {
portalType = "CALSResearch";
} else if (appName.equalsIgnoreCase("CALS Impact")) {
portalType = "CALSImpact";
} else if (appName.equalsIgnoreCase("VIVO")){
portalType = "VIVO";
} else {
portalType = "clone";
}
body.put("portalType", portalType);
// Not used in template. Is it used in processing the form?
if (vreq.getHeader("Referer") == null) {
vreq.getSession().setAttribute("commentsFormReferer","none");
} else {
vreq.getSession().setAttribute("commentsFormReferer",vreq.getHeader("Referer"));
}
bodyTemplate = "commentForm/form.ftl";
}
return mergeBodyToTemplate(bodyTemplate, body);
}
}

View file

@ -0,0 +1,378 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
public class ContactMailController extends FreeMarkerHttpServlet {
private static final Logger LOG = Logger.getLogger(ContactMailController.class);
private final static String CONFIRM_PAGE = "/thankyou.jsp";
private final static String ERR_PAGE = "/contact_err.jsp";
private final static String SPAM_MESSAGE = "Your message was flagged as spam.";
private final static String EMAIL_BACKUP_FILE_PATH = "/WEB-INF/LatestMessage.html";
private final static String WEB_USERNAME_PARAM = "webusername";
private final static String WEB_USEREMAIL_PARAM = "webuseremail";
private final static String COMMENTS_PARAM = "s34gfd88p9x1";
private static String smtpHost = null;
public void init(ServletConfig servletConfig) throws javax.servlet.ServletException {
super.init(servletConfig);
smtpHost = getSmtpHostFromProperties();
}
public static boolean isSmtpHostConfigured() {
if( smtpHost==null || smtpHost.equals("")) {
return false;
}
return true;
}
public static String getSmtpHostFromProperties() {
String host = ConfigurationProperties.getProperty("Vitro.smtpHost");
if (host != null && !host.equals("")) {
LOG.debug("Found Vitro.smtpHost value of " + host);
} else {
LOG.debug("No Vitro.smtpHost specified");
}
return (host != null && host.length() > 0) ? host : null;
}
protected String getTitle() {
return appName + " Feedback Form";
}
protected String getBody() {
Map<String, Object> body = new HashMap<String, Object>();
String bodyTemplate = null;
String statusMsg = null; // holds the error status
if (!isSmtpHostConfigured()) {
body.put("errorMessage",
"This application has not yet been configured to send mail. " +
"An smtp host has not been specified in the configuration properties file.");
bodyTemplate = "commentForm/error.ftl";
}
else {
String webusername = vreq.getParameter(WEB_USERNAME_PARAM);
String webuseremail = vreq.getParameter(WEB_USEREMAIL_PARAM);
String comments = vreq.getParameter(COMMENTS_PARAM);
String validationMessage = validateInput(webusername, webuseremail,
comments);
if (validationMessage != null) {
// rjy7 We should reload the form, not go to the error page!
body.put("errorMessage",
"Invalid submission");
bodyTemplate = "commentForm/error.ftl";
}
else {
webusername = webusername.trim();
webuseremail = webuseremail.trim();
comments = comments.trim();
String spamReason = null;
String originalReferer = (String) vreq.getSession().getAttribute("commentsFormReferer");
if (originalReferer != null) {
vreq.getSession().removeAttribute("commentsFormReferer");
/* does not support legitimate clients that don't send the Referer header
String referer = request.getHeader("Referer");
if (referer == null ||
(referer.indexOf("comments") <0
&& referer.indexOf("correction") <0) ) {
spamReason = "The form was not submitted from the " +
"Contact Us or Corrections page.";
statusMsg = SPAM_MESSAGE;
}
*/
} else {
originalReferer = "none";
}
if (spamReason == null) {
spamReason = checkForSpam(comments);
if (spamReason != null) {
statusMsg = SPAM_MESSAGE;
}
}
String formType = vreq.getParameter("DeliveryType");
String[] deliverToArray = null;
int recipientCount = 0;
String deliveryfrom = null;
if ("comment".equals(formType)) {
if (portal.getContactMail() == null || portal.getContactMail().trim().length()==0) {
LOG.error("No contact mail address defined in current portal "+portal.getPortalId());
throw new Error(
"To establish the Contact Us mail capability the system administrators must "
+ "specify an email address in the current portal.");
} else {
deliverToArray = portal.getContactMail().split(",");
}
deliveryfrom = "Message from the "+portal.getAppName()+" Contact Form";
} else if ("correction".equals(formType)) {
if (portal.getCorrectionMail() == null || portal.getCorrectionMail().trim().length()==0) {
LOG.error("Expecting one or more correction email addresses to be specified in current portal "+portal.getPortalId()+"; will attempt to use contact mail address");
if (portal.getContactMail() == null || portal.getContactMail().trim().length()==0) {
LOG.error("No contact mail address or correction mail address defined in current portal "+portal.getPortalId());
} else {
deliverToArray = portal.getContactMail().split(",");
}
} else {
deliverToArray = portal.getCorrectionMail().split(",");
}
deliveryfrom = "Message from the "+portal.getAppName()+" Correction Form (ARMANN-nospam)";
} else {
deliverToArray = portal.getContactMail().split(",");
statusMsg = SPAM_MESSAGE ;
spamReason = "The form specifies no delivery type.";
}
recipientCount=(deliverToArray == null) ? 0 : deliverToArray.length;
if (recipientCount == 0) {
LOG.error("recipientCount is 0 when DeliveryType specified as \""+formType+"\"");
throw new Error(
"To establish the Contact Us mail capability the system administrators must "
+ "specify at least one email address in the current portal.");
}
String msgText = composeEmail(webusername, webuseremail, comments,
deliveryfrom, originalReferer, vreq.getRemoteAddr());
// debugging
FileWriter fw = null;
try {
fw = new FileWriter(context.getRealPath(EMAIL_BACKUP_FILE_PATH),true);
}
catch (IOException e){
LOG.error("Can't open file to write email backup");
}
PrintWriter outFile = new PrintWriter(fw);
writeBackupCopy(outFile, msgText, spamReason);
// Set the smtp host
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true);
try {
if (spamReason == null) {
sendMessage(s, webuseremail, deliverToArray, deliveryfrom,
recipientCount, msgText);
}
} catch (AddressException e) {
statusMsg = "Please supply a valid email address.";
outFile.println( statusMsg );
outFile.println( e.getMessage() );
} catch (SendFailedException e) {
statusMsg = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]";
outFile.println( statusMsg );
outFile.println( e.getMessage() );
} catch (MessagingException e) {
statusMsg = "The system was unable to deliver your mail. Please try again later. [MESSAGING]";
outFile.println( statusMsg );
outFile.println( e.getMessage() );
e.printStackTrace();
}
outFile.flush();
outFile.close();
// Message was sent successfully
if (statusMsg == null && spamReason == null) {
bodyTemplate = "commentForm/confirmation.ftl";
} else {
body.put("errorMessage", statusMsg);
bodyTemplate = "commentForm/error.ftl";
}
}
}
return mergeBodyToTemplate(bodyTemplate, body);
}
/** Intended to mangle url so it can get through spam filtering
* http://host/dir/servlet?param=value -> host: dir/servlet?param=value */
public String stripProtocol( String in ){
if( in == null )
return "";
else
return in.replaceAll("http://", "host: " );
}
private String composeEmail(String webusername, String webuseremail,
String comments, String deliveryfrom,
String originalReferer, String ipAddr) {
StringBuffer msgBuf = new StringBuffer();
// contains the intro copy for the body of the email message
String lineSeparator = System.getProperty("line.separator");
// \r\n on windows, \n on unix
// from MyLibrary
msgBuf.setLength(0);
msgBuf.append("Content-Type: text/html; charset='us-ascii'" + lineSeparator);
msgBuf.append("<html>" + lineSeparator );
msgBuf.append("<head>" + lineSeparator );
msgBuf.append("<style>a {text-decoration: none}</style>" + lineSeparator );
msgBuf.append("<title>" + deliveryfrom + "</title>" + lineSeparator );
msgBuf.append("</head>" + lineSeparator );
msgBuf.append("<body>" + lineSeparator );
msgBuf.append("<h4>" + deliveryfrom + "</h4>" + lineSeparator );
msgBuf.append("<h4>From: "+webusername +" (" + webuseremail + ")" +
" at IP address " + ipAddr + "</h4>"+lineSeparator);
if (!(originalReferer == null || originalReferer.equals("none"))){
//The spam filter that is being used by the listsrv is rejecting <a href="...
//so try with out the markup, if that sill doesn't work,
//uncomment the following line to strip the http://
//msgBuf.append("<p><i>likely viewing page " + stripProtocol(originalReferer) );
msgBuf.append("<p><i>likely viewing page " + originalReferer );
}
msgBuf.append(lineSeparator + "</i></p><h3>Comments:</h3>" + lineSeparator );
if (comments==null || comments.equals("")) {
msgBuf.append("<p>BLANK MESSAGE</p>");
} else {
msgBuf.append("<p>"+comments+"</p>");
}
msgBuf.append("</body>" + lineSeparator );
msgBuf.append("</html>" + lineSeparator );
return msgBuf.toString();
}
private void writeBackupCopy(PrintWriter outFile, String msgText,
String spamReason) {
Calendar cal = Calendar.getInstance();
outFile.println("<hr/>");
outFile.println();
outFile.println("<p>"+cal.getTime()+"</p>");
outFile.println();
if (spamReason != null) {
outFile.println("<p>REJECTED - SPAM</p>");
outFile.println("<p>"+spamReason+"</p>");
outFile.println();
}
outFile.print( msgText );
outFile.println();
outFile.println();
outFile.flush();
// outFile.close();
}
private void sendMessage(Session s, String webuseremail,
String[] deliverToArray, String deliveryfrom, int recipientCount,
String msgText)
throws AddressException, SendFailedException, MessagingException {
// Construct the message
MimeMessage msg = new MimeMessage( s );
//System.out.println("trying to send message from servlet");
// Set the from address
msg.setFrom( new InternetAddress( webuseremail ));
// Set the recipient address
if (recipientCount>0){
InternetAddress[] address=new InternetAddress[recipientCount];
for (int i=0; i<recipientCount; i++){
address[i] = new InternetAddress(deliverToArray[i]);
}
msg.setRecipients( Message.RecipientType.TO, address );
}
// Set the subject and text
msg.setSubject( deliveryfrom );
// add the multipart to the message
msg.setContent(msgText,"text/html");
// set the Date: header
msg.setSentDate( new Date() );
Transport.send( msg ); // try to send the message via smtp - catch error exceptions
}
private String validateInput(String webusername, String webuseremail,
String comments) {
if( webusername == null || "".equals(webusername.trim()) ){
return "A proper webusername field was not found in the form submitted.";
}
if( webuseremail == null || "".equals(webuseremail.trim()) ){
return "A proper webuser email field was not found in the form submitted.";
}
if (comments==null || "".equals(comments.trim())) {
return "The proper comments field was not found in the form submitted.";
}
return null;
}
/**
* @param request
* @return null if message not judged to be spam, otherwise a String
* containing the reason the message was flagged as spam.
*/
private String checkForSpam(String comments) {
/* if this blog markup is found, treat comment as blog spam */
if (
(comments.indexOf("[/url]") > -1
|| comments.indexOf("[/URL]") > -1
|| comments.indexOf("[url=") > -1
|| comments.indexOf("[URL=") > -1)) {
return "The message contained blog link markup.";
}
/* if message is absurdly short, treat as blog spam */
if (comments.length()<15) {
return "The message was too short.";
}
return null;
}
}

View file

@ -90,7 +90,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
root.put("body", getBody());
}
protected void setSharedVariable(String key, String value) {
protected void setSharedVariable(String key, Object value) {
try {
config.setSharedVariable(key, value);
} catch (TemplateModelException e) {
@ -134,6 +134,7 @@ 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;
@ -199,18 +200,10 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
// 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();
try {
config.setSharedVariable("portalId", portalId);
} catch (TemplateModelException e) {
log.error("Can't set shared variable 'portalId'.");
}
setSharedVariable("portalId", portalId);
appName = portal.getAppName();
try {
config.setSharedVariable("appName", appName);
} catch (TemplateModelException e) {
log.error("Can't set shared variable 'appName'.");
}
setSharedVariable("siteName", appName);
setTemplateLoader();
@ -221,23 +214,20 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
PortalWebUtil.populateSearchOptions(portal, appBean, vreq.getWebappDaoFactory().getPortalDao());
PortalWebUtil.populateNavigationChoices(portal, vreq, appBean, vreq.getWebappDaoFactory().getPortalDao());
// We'll need to separate theme-general and theme-specific stylesheet
// dirs, so we need either two attributes or a list.
String themeDir = portal.getThemeDir();
String stylesheetDir = getUrl(themeDir + "css/");
try {
config.setSharedVariable("stylesheetDir", stylesheetDir);
} catch (TemplateModelException e) {
log.error("Can't set shared variable 'stylesheetDir'.");
}
root.put("siteName", portal.getAppName());
root.put("tagline", portal.getShortHand());
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(request));
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(vreq));
String themeDir = portal.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);
}
// Define the URLs that are accessible to the templates. Note that we do not create menus here,
@ -248,8 +238,8 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
// view to control which links go where, and the link text and title.
Map<String, String> urls = new HashMap<String, String>();
String homeUrl = (portal.getRootBreadCrumbURL()!=null && portal.getRootBreadCrumbURL().length()>0) ?
portal.getRootBreadCrumbURL() : vreq.getContextPath()+"/";
String rootBreadCrumbUrl = portal.getRootBreadCrumbURL();
String homeUrl = StringUtils.isEmpty(rootBreadCrumbUrl) ? contextPath : rootBreadCrumbUrl;
urls.put("home", homeUrl);
String bannerImage = portal.getBannerImage();
@ -262,7 +252,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
urls.put("about", getUrl(Router.ABOUT, portalParam));
if (ContactMailServlet.getSmtpHostFromProperties() != null) {
urls.put("contact", getUrl(Router.CONTACT, portalParam));
urls.put("contact", getUrl(Router.COMMENT_FORM, portalParam));
}
urls.put("search", getUrl(Router.SEARCH));
urls.put("termsOfUse", getUrl(Router.TERMS_OF_USE, portalParam));
@ -270,7 +260,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
urls.put("logout", getUrl(Router.LOGOUT));
urls.put("siteAdmin", getUrl(Router.SITE_ADMIN));
root.put("urls", urls);
setSharedVariable("urls", urls);
}
private final void setLoginInfo() {
@ -311,6 +301,18 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
root.put("copyright", copyright);
}
}
private final void setThemeInfo(String themeDir) {
setSharedVariable("themeDir", getUrl(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("siteIconDir", getUrl(themeDir + "site_icons/"));
}
// Define template locations. Template loader will look first in the theme-specific
// location, then in the vitro location.

View file

@ -8,7 +8,6 @@ public class Router {
public static final String ABOUT = "/about";
public static final String BROWSE = "/browse";
public static final String CONTACT= "/comments"; // temporary - FreeMarkerHttpServlet in svn is looking for it
public static final String COMMENT_FORM = "/comments";
public static final String INDIVIDUAL = "/individual";
public static final String INDIVIDUAL_LIST = "/entitylist"; // change

View file

@ -23,15 +23,13 @@ public class TermsOfUseController extends FreeMarkerHttpServlet {
Map<String, Object> body = new HashMap<String, Object>();
String websiteName = portal.getRootBreadCrumbAnchor();
if (StringUtils.isEmpty(websiteName)) {
websiteName = appName;
}
String rootBreadCrumbAnchor = portal.getRootBreadCrumbAnchor();
String websiteName = StringUtils.isEmpty(rootBreadCrumbAnchor) ? appName : rootBreadCrumbAnchor;
body.put("websiteName", websiteName);
body.put("copyrightAnchor", portal.getCopyrightAnchor());
String templateName = "body/termsOfUse.ftl";
return mergeBodyToTemplate(templateName, body);
String bodyTemplate = "termsOfUse.ftl";
return mergeBodyToTemplate(bodyTemplate, body);
}
}

View file

@ -46,7 +46,7 @@
<form name = "contact_form" action="sendmail" method="post" onsubmit="return ValidateForm('contact_form');">
<input type="hidden" name="home" value="${portalId}"/>
<input type="hidden" name="RequiredFields" value="webusername,webuseremail,comments"/>
<input type="hidden" name="RequiredFields" value="webusername,webuseremail,s34gfd88p9x1"/>
<input type="hidden" name="RequiredFieldsNames" value="Name,Email address,Comments"/>
<input type="hidden" name="EmailFields" value="webuseremail"/>
<input type="hidden" name="EmailFieldsNames" value="emailaddress"/>

View file

@ -0,0 +1,75 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
function ValidateForm(formName) {
var x = 0; // counts form elements - used as array index
var y = 0; // counts required fields - used as array index
errors = false;
var errorList;
if (document.forms[formName].RequiredFields) {
errorList = 'Please fill out the following required fields:\n';
// build array of required fields
reqStr = document.forms[formName].RequiredFields.value;
requiredFields = reqStr.split(',');
// build array holding the names of required fields as
// displayed in error box
if (document.forms[formName].RequiredFieldsNames) {
reqNameStr = document.forms[formName].RequiredFieldsNames.value;
} else {
reqNameStr = document.forms[formName].RequiredFields.value;
}
requiredNames = reqNameStr.split(',');
// Loop through form elements, checking for required fields
while ((x < document.forms[formName].elements.length)) {
if (document.forms[formName].elements[x].name == requiredFields[y]) {
if (document.forms[formName].elements[x].value == '') {
errorList += requiredNames[y] + '\n';
errors = true;
}
y++;
}
x++;
}
if (errors) {
alert(errorList);
return false;
}
x = 0;
y = 0;
}
// Check for Email formatting
if (document.forms[formName].EmailFields) {
errorList = 'Please format your e-mail address as: \"userid@institution.edu\" or enter another complete email address';
// build array of required fields
emailStr = document.forms[formName].EmailFields.value;
emailFields = emailStr.split(',');
// build array holding the names of required fields as
// displayed in error box
if (document.forms[formName].EmailFieldsNames) {
emailNameStr = document.forms[formName].EmailFieldsNames.value;
} else {
emailNameStr = document.forms[formName].EmailFields.value;
}
emailNames = emailNameStr.split(',');
// Loop through form elements, checking for required fields
while ((x < document.forms[formName].elements.length)) {
if (document.forms[formName].elements[x].name == emailFields[y]) {
if ((document.forms[formName].elements[x].value.indexOf('@') < 1)
|| (document.forms[formName].elements[x].value.lastIndexOf('.') < document.forms[formName].elements[x].value.indexOf('@')+1)) {
errors = true;
}
y++;
}
x++;
}
if (errors) {
alert(errorList);
return false;
}
x = 0;
y = 0;
}
return true;
}

View file

@ -1,79 +0,0 @@
<!-- /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -->
<script language="JavaScript" type="text/javascript">
<!--
function ValidateForm(formName) {
var x = 0; // counts form elements - used as array index
var y = 0; // counts required fields - used as array index
errors = false;
var errorList;
if (document.forms[formName].RequiredFields) {
errorList = 'Please fill out the following required fields:\n';
// build array of required fields
reqStr = document.forms[formName].RequiredFields.value;
requiredFields = reqStr.split(',');
// build array holding the names of required fields as
// displayed in error box
if (document.forms[formName].RequiredFieldsNames) {
reqNameStr = document.forms[formName].RequiredFieldsNames.value;
} else {
reqNameStr = document.forms[formName].RequiredFields.value;
}
requiredNames = reqNameStr.split(',');
// Loop through form elements, checking for required fields
while ((x < document.forms[formName].elements.length)) {
if (document.forms[formName].elements[x].name == requiredFields[y]) {
if (document.forms[formName].elements[x].value == '') {
errorList += requiredNames[y] + '\n';
errors = true;
}
y++;
}
x++;
}
if (errors) {
alert(errorList);
return false;
}
x = 0;
y = 0;
}
// Check for Email formatting
if (document.forms[formName].EmailFields) {
errorList = 'Please format your e-mail address as: \"userid@institution.edu\" or enter another complete email address';
// build array of required fields
emailStr = document.forms[formName].EmailFields.value;
emailFields = emailStr.split(',');
// build array holding the names of required fields as
// displayed in error box
if (document.forms[formName].EmailFieldsNames) {
emailNameStr = document.forms[formName].EmailFieldsNames.value;
} else {
emailNameStr = document.forms[formName].EmailFields.value;
}
emailNames = emailNameStr.split(',');
// Loop through form elements, checking for required fields
while ((x < document.forms[formName].elements.length)) {
if (document.forms[formName].elements[x].name == emailFields[y]) {
if ((document.forms[formName].elements[x].value.indexOf('@') < 1)
|| (document.forms[formName].elements[x].value.lastIndexOf('.') < document.forms[formName].elements[x].value.indexOf('@')+1)) {
errors = true;
}
y++;
}
x++;
}
if (errors) {
alert(errorList);
return false;
}
x = 0;
y = 0;
}
return true;
}
-->
</script>

View file

@ -0,0 +1,7 @@
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
<%
String contextPath = request.getContextPath();
%>
<script language="JavaScript" type="text/javascript" src="<%= contextPath %>/js/commentForm.js"></script>

View file

@ -5,12 +5,14 @@
<#if message??>
<p>${message}</p>
<#else>
<#list classGroups as classGroup>
<h2>${classGroup.publicName}</h2>
<ul>
<#list classGroup.classes as class>
<li><a href="${class.url}">${class.name}</a> (${class.entityCount})</li>
</#list>
</ul>
</#list>
</#if>
<div class="siteMap">
<#list classGroups as classGroup>
<h2>${classGroup.publicName}</h2>
<ul>
<#list classGroup.classes as class>
<li><a href="${class.url}">${class.name}</a> (${class.entityCount})</li>
</#list>
</ul>
</#list>
</div>
</#if>

View file

@ -0,0 +1,9 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Confirmation page for comment form -->
<h2>Thank you for your feedback</h2>
<img src="${siteIconDir}/mail.gif" alt="mailbox"/><br/>
<p>Thank you for contacting our curation and development team. We will respond to your inquiry as soon as possible.</p>
<p>Return to the <a href="${urls.home}">home page</a>.</p>

View file

@ -0,0 +1,3 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Comment form email response -->

View file

@ -0,0 +1,13 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<img src="${siteIconDir}/bomb.gif" alt="email error"/>
<p class="normal">An error occurred during the processing of your request.<br />
<#if errorMessage?has_content>
<strong>${errorMessage}</strong>
</#if>
</p>
<p>Return to the <a href="${urls.home}">home page</a>.</p>

View file

@ -0,0 +1,59 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Comment form -->
<div class="staticPageBackground feedbackForm">
<h2>${title}</h2>
<p>Thank you for your interest in
<#compress>
<#if portalType == "CALSResearch">
the Cornell University College of Agriculture and Life Sciences Research Portal
<#elseif portalType == "VIVO">
VIVO
<#else>
the ${siteName} portal
</#if>
</#compress>.
Please submit this form with questions, comments, or feedback about the content of this site.
</p>
<#if siteName == "CALSResearch" || siteName == "CALSImpact">
<p>
${siteName} is a service that depends on regular updates and feedback.
Please help us out by providing comments and suggestions for additional content (people, departments, courses, research services, etc.)
that you would like to see represented. The reference librarians at Albert R. Mann Library will be in touch with you soon.
</p>
</#if>
<form name="contact_form" action="sendMail" 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"/>
<input type="hidden" name="EmailFields" value="webuseremail"/>
<input type="hidden" name="EmailFieldsNames" value="emailaddress"/>
<input type="hidden" name="DeliveryType" value="comment"/>
<label for="webusername">Full name</label>
<p><input style="width:33%;" type="text" name="webusername" maxlength="255"/></p>
<label for="webuseremail">Email address</label>
<p><input style="width:25%;" type="text" name="webuseremail" maxlength="255"/></p>
<label>Your comments, questions, or suggestions</label>
<textarea name="s34gfd88p9x1" rows="10" cols="90"></textarea>
<div>
<input type="submit" value="Send Mail" class="yellowbutton"/>
<input type="reset" value="Clear Form" class="plainbutton"/>
</div
<p style="font-weight: bold; margin-top: 1em">Thank you!</p>
</form>
</div>
<#-- RY This is temporary. -->
<script src="${contextPath}/js/commentForm.js"></script>

View file

@ -17,10 +17,10 @@
<p class="normal">${copyrightAnchor} makes no warranty, expressed or implied, including the warranties of merchantability
and fitness for a particular purpose, or assumes any legal liability or responsibility for the accuracy,
completeness, currency or usefulness of any material displayed or distributed through the
${appName} website or represents that its use would not infringe privately owned rights.
${siteName} website or represents that its use would not infringe privately owned rights.
${copyrightAnchor} disclaims all warranties with regard to the information provided. Any reliance upon such information
is at your own risk. In no event will ${copyrightAnchor} be liable to you for any damages or losses whatsoever resulting
from or caused by the ${appName} website or its contents.</p>
from or caused by the ${siteName} website or its contents.</p>
<h3>Disclaimer of Endorsement</h3>
<p class="normal">Reference herein to any specific commercial product, process, or service by trade name,

View file

@ -24,5 +24,3 @@
All Rights Reserved. <a href="${urls.termsOfUse}">Terms of Use</a>
</div>
<#-- SCRIPT TAGS SHOULD GO HERE -->

View file

@ -0,0 +1,21 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- NOTICE: This is SAMPLE Google Analytics code. You must replace it with your institution's code. -->
<#--
<script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-5164622-5");
pageTracker._setDomainName("vivo.cornell.edu");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
var rollupTracker = _gat._getTracker("UA-12531954-1");
rollupTracker._setDomainName("none");
rollupTracker._setAllowLinker(true);
rollupTracker._trackPageview(location.host+location.pathname);
}
catch(err) {}
</script>
-->

View file

@ -1 +1,5 @@
<#-- $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$ -->
<#include "googleAnalytics.ftl">
<#-- OTHER SCRIPT TAGS HERE -->

View file

@ -3,6 +3,8 @@
<link rel="stylesheet" type="text/css" href="${stylesheetDir}screen.css" media="screen"/>
<link rel="stylesheet" type="text/css" href="${stylesheetDir}print.css" media="print"/>
<#list stylesheets as stylesheet>
${stylesheet}
</#list>
<#if stylesheeets??>
<#list stylesheets as stylesheet>
${stylesheet}
</#list>
</#if>

View file

@ -22,7 +22,7 @@
<hr class="hidden" />
<div id="contentwrap">
<div id="content" <#if contentClass??> class="${contentClass}" </#if>>
<div id="content">
<#-- We don't do title here because some pages don't get a title, or it may not be the same as the <title> text.
<h2>${title}</h2> -->
${body}
@ -31,6 +31,8 @@
<#include "/components/footer.ftl">
</div> <!-- wrap -->
</div> <!-- wrap -->
<#include "/components/scripts.ftl">
</body>
</html>