From 72d43f05a5a7792e27e82e91b0fdf4c63f4add61 Mon Sep 17 00:00:00 2001 From: rjy7 Date: Tue, 21 Sep 2010 16:05:36 +0000 Subject: [PATCH] NIHVIVO-650 Display image on new (Freemarker) individual profile page. Add <@url /> directive to generate img src value. --- .../controller/edit/ReorderController.java | 7 +- .../freemarker/FreemarkerHttpServlet.java | 13 +-- .../freemarker/IndividualController.java | 50 +---------- .../controller/freemarker/UrlBuilder.java | 13 ++- .../controller/AutocompleteController.java | 32 +++---- .../webapp/web/directives/UrlDirective.java | 85 +++++++++++++++++++ .../IndividualTemplateModel.java | 31 +++++-- .../body/{ => individual}/individual-help.ftl | 0 .../body/{ => individual}/individual.ftl | 52 ++++++++---- .../web/templates/freemarker/lib/lib-list.ftl | 8 +- .../templates/freemarker/lib/lib-property.ftl | 43 ++++++++++ 11 files changed, 216 insertions(+), 118 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/UrlDirective.java rename webapp/web/templates/freemarker/body/{ => individual}/individual-help.ftl (100%) rename webapp/web/templates/freemarker/body/{ => individual}/individual.ftl (54%) create mode 100644 webapp/web/templates/freemarker/lib/lib-property.ftl diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ReorderController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ReorderController.java index 0e7d8b5b1..6f7c1ce26 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ReorderController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ReorderController.java @@ -32,11 +32,6 @@ public class ReorderController extends PrimitiveRdfEdit { @Override protected void processRequest(VitroRequest vreq, HttpServletResponse response) { - //String templateName = "autocompleteResults.ftl"; - //Map map = new HashMap(); - //Configuration config = getConfig(vreq); - //PortalFlag portalFlag = vreq.getPortalFlag(); - String errorMsg = null; String rankPredicate = vreq.getParameter(RANK_PREDICATE_PARAMETER_NAME); if (rankPredicate == null) { @@ -45,7 +40,7 @@ public class ReorderController extends PrimitiveRdfEdit { doError(response, errorMsg, HttpServletResponse.SC_BAD_REQUEST ); return; } - + String[] individualUris = vreq.getParameterValues(INDIVIDUAL_PREDICATE_PARAMETER_NAME); if (individualUris == null || individualUris.length == 0) { errorMsg = "No individuals specified"; 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 0f4efd510..457102ace 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 @@ -431,6 +431,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { map.put("dump", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.DumpDirective()); map.put("dumpAll", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.DumpAllDirective()); map.put("help", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.HelpDirective()); + map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective()); return map; } @@ -897,18 +898,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { "This is not a template response."); } - @Override - public int getStatusCode() { - throw new UnsupportedOperationException( - "This is not a BaseResponseValues response."); - } - - @Override - public void setStatusCode(int statusCode) { - throw new UnsupportedOperationException( - "This is not a BaseResponseValues response."); - } - @Override public Map getMap() { throw new UnsupportedOperationException( diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java index 1b1eef960..8d5d45862 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java @@ -241,63 +241,17 @@ public class IndividualController extends FreemarkerHttpServlet { // if (customView!=null) { // // insert test for whether a css files of the same name exists, and populate the customCss string for use when construction the header // } - //String netid = iwDao.getNetId(indiv.getURI()); - - //data.put("netid", netid); - //data.put("vclassName", vclassName); - // RY We should not have references to a specific ontology in the vitro code! - // Figure out how to move this out of here. - boolean isPerson = individual.isVClass("http://xmlns.com/foaf/0.1/Person"); - map.put("isPerson", isPerson); - if (isPerson) { - map.put("visualizationUrl", UrlBuilder.getUrl("/visualization", - "uri", individual.getURI())); - } - - // RY Would like to use IndividualTemplateModel object, but may just end up copying all methods. Since object is put in template - // with a read-only wrapper, it should be restrictive enough. - map.put("individual",individual); //data.put("individual", new IndividualTemplateModel(indiv)); - //Portal portal = vreq.getPortal(); - //data.put("portal",String.valueOf(portal)); -// String view= getViewFromRequest(vreq); -// if( view == null){ -// if (customView == null) { -// view = default_jsp; -// data.put("bodyJsp","/"+Controllers.ENTITY_JSP); -// log.debug("no custom view and no view parameter in request for rendering "+indiv.getName()); -// } else { -// view = default_jsp; -// log.debug("setting custom view templates/entity/"+ customView + " for rendering "+indiv.getName()); -// data.put("bodyJsp", "/templates/entity/"+customView); -// } -// data.put("entityPropsListJsp",Controllers.ENTITY_PROP_LIST_JSP); -// data.put("entityDatapropsListJsp",Controllers.ENTITY_DATAPROP_LIST_JSP); -// data.put("entityMergedPropsListJsp",Controllers.ENTITY_MERGED_PROP_LIST_GROUPED_JSP); -// data.put("entityKeywordsListJsp",Controllers.ENTITY_KEYWORDS_LIST_JSP); -// } else { -// log.debug("Found view parameter "+view+" in request for rendering "+indiv.getName()); -// } + map.put("individual", new IndividualTemplateModel(individual)); //setup highlighter for search terms - checkForSearch(vreq, individual); + //checkForSearch(vreq, individual); if( individual.getURI().startsWith( vreq.getWebappDaoFactory().getDefaultNamespace() )){ map.put("entityLinkedDataURL", individual.getURI() + "/" + individual.getLocalName() + ".rdf"); } - - // generate link to RDF representation for semantic web clients like Piggy Bank - // BJL 2008-07-16: I'm temporarily commenting this out because I forgot we need to make sure it filters out the hidden properties - // generate url for this entity - // String individualToRDF = "http://"+vreq.getServerName()+":"+vreq.getServerPort()+vreq.getContextPath()+"/entity?home=1&uri="+forURL(entity.getURI())+"&view=rdf.rdf"; - //css += ""; - - - //RequestDispatcher rd = vreq.getRequestDispatcher( view ); - //rd.forward(vreq,res); - return map; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java index a55fc7e07..767dbd239 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java @@ -29,15 +29,14 @@ public class UrlBuilder { BROWSE("/browse"), CONTACT("/contact"), INDIVIDUAL("/individual"), - INDIVIDUAL_LIST("/individuallist"), - SEARCH("/search"), - TERMS_OF_USE("/termsOfUse"), - - // RY put these under /admin/ + INDIVIDUAL_LIST("/individuallist"), LOGIN("/siteAdmin"), LOGOUT("/login_process.jsp"), - SITE_ADMIN("/siteAdmin"); - + SEARCH("/search"), + SITE_ADMIN("/siteAdmin"), + TERMS_OF_USE("/termsOfUse"), + VISUALIZATION("/visualization"); + private final String path; Route(String path) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/AutocompleteController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/AutocompleteController.java index 7b0430d19..285bf62dd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/AutocompleteController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/AutocompleteController.java @@ -63,7 +63,9 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(AutocompleteController.class); - + + private static final String TEMPLATE_DEFAULT = "autocompleteResults.ftl"; + private static String QUERY_PARAMETER_NAME = "term"; private IndexSearcher searcher = null; @@ -92,8 +94,6 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - // String templateName = request.getServletPath().equals("/autocomplete") ? "autocompleteResults.ftl" : "selectResults.ftl"; - String templateName = "autocompleteResults.ftl"; Map map = new HashMap(); VitroRequest vreq = new VitroRequest(request); @@ -106,7 +106,7 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea if( vreq.getWebappDaoFactory() == null || vreq.getWebappDaoFactory().getIndividualDao() == null ){ log.error("makeUsableBeans() could not get IndividualDao "); - doSearchError(templateName, map, config, response); + doSearchError(map, config, response); return; } IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao(); @@ -122,7 +122,7 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea log.debug("query for '" + qtxt +"' is " + query.toString()); if (query == null ) { - doNoQuery(templateName, map, config, response); + doNoQuery(map, config, response); return; } @@ -139,20 +139,20 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea topDocs = searcherForRequest.search(query,null,maxHitSize); }catch (Exception ex){ log.error(ex); - doFailedSearch(templateName, map, config, response); + doFailedSearch(map, config, response); return; } } if( topDocs == null || topDocs.scoreDocs == null){ log.error("topDocs for a search was null"); - doFailedSearch(templateName, map, config, response); + doFailedSearch(map, config, response); return; } int hitsLength = topDocs.scoreDocs.length; if ( hitsLength < 1 ){ - doFailedSearch(templateName, map, config, response); + doFailedSearch(map, config, response); return; } log.debug("found "+hitsLength+" hits"); @@ -176,11 +176,11 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea Collections.sort(results); map.put("results", results); - writeTemplate(templateName, map, config, response); + writeTemplate(TEMPLATE_DEFAULT, map, config, response); } catch (Throwable e) { log.error("AutocompleteController(): " + e); - doSearchError(templateName, map, config, response); + doSearchError(map, config, response); return; } } @@ -441,18 +441,18 @@ public class AutocompleteController extends FreemarkerHttpServlet implements Sea } - private void doNoQuery(String templateName, Map map, Configuration config, HttpServletResponse response) { - writeTemplate(templateName, map, config, response); + private void doNoQuery(Map map, Configuration config, HttpServletResponse response) { + writeTemplate(TEMPLATE_DEFAULT, map, config, response); } - private void doFailedSearch(String templateName, Map map, Configuration config, HttpServletResponse response) { - writeTemplate(templateName, map, config, response); + private void doFailedSearch(Map map, Configuration config, HttpServletResponse response) { + writeTemplate(TEMPLATE_DEFAULT, map, config, response); } - private void doSearchError(String templateName, Map map, Configuration config, HttpServletResponse response) { + private void doSearchError(Map map, Configuration config, HttpServletResponse response) { // For now, we are not sending an error message back to the client because with the default autocomplete configuration it // chokes. - writeTemplate(templateName, map, config, response); + writeTemplate(TEMPLATE_DEFAULT, map, config, response); } public static final int MAX_QUERY_LENGTH = 500; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/UrlDirective.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/UrlDirective.java new file mode 100644 index 000000000..10d3950bc --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/UrlDirective.java @@ -0,0 +1,85 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.web.directives; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; +import freemarker.core.Environment; +import freemarker.template.Configuration; +import freemarker.template.TemplateDirectiveBody; +import freemarker.template.TemplateException; +import freemarker.template.TemplateModel; +import freemarker.template.TemplateModelException; + +/** + * Template directive to be used to get image src values. + * Parameters are not needed, therefore not supported. + * @author rjy7 + * + */ +public class UrlDirective extends BaseTemplateDirectiveModel { + + private static final Log log = LogFactory.getLog(UrlDirective.class); + + @Override + public void execute(Environment env, Map params, TemplateModel[] loopVars, + TemplateDirectiveBody body) throws TemplateException, IOException { + + if (loopVars.length != 0) { + throw new TemplateModelException( + "The url directive doesn't allow loop variables."); + } + + if (body != null) { + throw new TemplateModelException( + "The url directive doesn't allow nested content."); + } + + String path = params.get("path").toString(); + if (path == null) { + throw new TemplateModelException( + "The url directive requires a value for parameter 'path'."); + } + + if (!path.startsWith("/")) { + throw new TemplateModelException( + "The url directive requires that the value of parameter 'path' is an absolute path starting with '/'."); + } + + String url = UrlBuilder.getUrl(path); + Writer out = env.getOut(); + out.write(url); + } + + public String help(Configuration config) { + Map map = new HashMap(); + + String name = getDirectiveName(); + map.put("name", name); + + map.put("effect", "Generate a full url from a path. Use for generating src attribute of image tags."); + + map.put("comments", "The path should be an absolute path, starting with '/'."); + + Map params = new HashMap(); + params.put("path", "path"); + map.put("params", params); + + List examples = new ArrayList(); + examples.add("<@" + name + " path=\"/images/dummyImages/person.thumbnail.jpg\" />"); + map.put("examples", examples); + + return mergeToHelpTemplate(map, config); + } + + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/IndividualTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/IndividualTemplateModel.java index bb32ea46a..c31fb02c0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/IndividualTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/IndividualTemplateModel.java @@ -14,6 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Link; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route; +import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; import edu.cornell.mannlib.vitro.webapp.web.ViewFinder; import edu.cornell.mannlib.vitro.webapp.web.ViewFinder.ClassView; @@ -58,6 +59,29 @@ public class IndividualTemplateModel extends BaseTemplateModel { return profileUrl; } + + public String getVisualizationUrl() { + return isPerson() ? getUrl(Route.VISUALIZATION.path(), "uri", getUri()) : null; + } + + // RY We should not have references to a specific ontology in the vitro code! + // Figure out how to move this out of here. + // We could subclass IndividualTemplateModel in the VIVO code and add the isPerson() + // and getVisualizationUrl() methods there, but we still need to know whether to + // instantiate the IndividualTemplateModel or the VivoIndividualTemplateModel class. + public boolean isPerson() { + return individual.isVClass("http://xmlns.com/foaf/0.1/Person"); + } + + public String getImageUrl() { + String imageUrl = individual.getImageUrl(); + return imageUrl == null ? null : getUrl(imageUrl); + } + + public String getThumbUrl() { + String thumbUrl = individual.getThumbUrl(); + return thumbUrl == null ? null : getUrl(thumbUrl); + } public String getSearchView() { return getView(ClassView.SEARCH); @@ -126,11 +150,4 @@ public class IndividualTemplateModel extends BaseTemplateModel { return individual.getKeywords(); } - public String getImageUrl() { - return individual.getImageUrl(); - } - - public String getThumbUrl() { - return individual.getThumbUrl(); - } } diff --git a/webapp/web/templates/freemarker/body/individual-help.ftl b/webapp/web/templates/freemarker/body/individual/individual-help.ftl similarity index 100% rename from webapp/web/templates/freemarker/body/individual-help.ftl rename to webapp/web/templates/freemarker/body/individual/individual-help.ftl diff --git a/webapp/web/templates/freemarker/body/individual.ftl b/webapp/web/templates/freemarker/body/individual/individual.ftl similarity index 54% rename from webapp/web/templates/freemarker/body/individual.ftl rename to webapp/web/templates/freemarker/body/individual/individual.ftl index 321d77bf5..a90a42b69 100644 --- a/webapp/web/templates/freemarker/body/individual.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual.ftl @@ -2,12 +2,18 @@ <#-- Template for individual profile page --> +<#import "lib-property.ftl" as p> + +<#assign editingClass> + <#if editStatus.showEditLinks>editing<#else> + +
<#if editStatus.showAdminPanel> <#include "individual-adminPanel.ftl"> -
+
<#if relatedSubject??> @@ -15,34 +21,44 @@

← return to ${relatedSubject.name}

<#else> <#-- Label --> -
-
-

${individual.name}

- <#if editStatus.showEditLinks> - -
-
+ <@p.dataPropWrapper id="label"> +

${individual.name}

+ <#-- Moniker --> <#if individual.moniker?has_content> -
-
-
- ${individual.moniker} -
-
-
+ <@p.dataPropsWrapper id="moniker"> + ${individual.moniker} +
- <#include "individual-sparklineVisualization.ftl"> - + <#include "individual-sparklineVisualization.ftl"> + +
+ <#if individual.thumbUrl??> + <@p.dataPropsWrapper id="thumbnail"> + + ${individual.name} + + + <#elseif individual.person> + <@p.dataPropsWrapper id="thumbnail"> + placeholder image + + +
+ + +
- ${stylesheets.addFromTheme("/entity.css")} <#-- RY Figure out which of these scripts really need to go into the head, and which are needed at all (e.g., tinyMCE??) --> diff --git a/webapp/web/templates/freemarker/lib/lib-list.ftl b/webapp/web/templates/freemarker/lib/lib-list.ftl index e5a75bb61..e529ad4cf 100644 --- a/webapp/web/templates/freemarker/lib/lib-list.ftl +++ b/webapp/web/templates/freemarker/lib/lib-list.ftl @@ -15,7 +15,7 @@
  • apples
  • bananas
  • oranges
  • - <@firstLastList> + RY Consider rewriting in Java. Probably designers won't want to modify this. That would allow us to support nested
  • elements. @@ -51,13 +51,13 @@
  • apples
  • ,
  • bananas
  • ,
  • oranges
  • - <@firstLastListNested> + <@firstLastListNested delim="??">
  • apples, oranges
  • ??
  • bananas, lemons
  • ??
  • grapefruit, limes
  • - <@firstLastListNested> + <@firstLastListNested delim="??">
  • Books @@ -72,7 +72,7 @@
  • Time
  • - <@firstLastListNested> + RY Consider rewriting in Java. Probably designers won't want to modify this. --> diff --git a/webapp/web/templates/freemarker/lib/lib-property.ftl b/webapp/web/templates/freemarker/lib/lib-property.ftl new file mode 100644 index 000000000..53fb2d0b1 --- /dev/null +++ b/webapp/web/templates/freemarker/lib/lib-property.ftl @@ -0,0 +1,43 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Macros for display of individual properties --> + +<#-- + Macro: dataPropWrapper + + Wrap a dataproperty in the appropriate divs + + Usage: + <@dataPropWrapper id="myId" editStatus=true> + <#nested> + +--> + +<#macro dataPropWrapper id editStatus=false> +
    +
    + <#nested> +
    +
    + + +<#----------------------------------------------------------------------------> + +<#-- + Macro: dataPropsWrapper + + Wrap a dataproperty in the appropriate divs + + Usage: + <@dataPropsWrapper id="myId" editStatus=true> + <#nested> + +--> + +<#macro dataPropsWrapper id editStatus=false> +
    + <@dataPropWrapper id=id editStatus=editStatus> + <#nested> + +
    +