From a0e7d70fd38285510e8f73d2fce9e4365f1343e6 Mon Sep 17 00:00:00 2001 From: j2blake Date: Tue, 23 Apr 2013 17:18:39 -0400 Subject: [PATCH 01/18] VIVO-12 Permit multi-language support in E-mails to users The Freemarker environment must have the request as a special attribute, so the I18nBundle can find the preferred languages. --- .../webapp/email/FreemarkerEmailFactory.java | 4 +-- .../webapp/email/FreemarkerEmailMessage.java | 32 ++++++++++++------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java index bedeab160..05e3c7a51 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java @@ -61,8 +61,8 @@ public class FreemarkerEmailFactory { FreemarkerEmailFactory factory = getFactory(vreq); FreemarkerConfiguration fConfig = FreemarkerConfigurationLoader .getConfig(vreq); - return new FreemarkerEmailMessage(fConfig, factory.getEmailSession(), - factory.getReplyToAddress()); + return new FreemarkerEmailMessage(vreq, fConfig, + factory.getEmailSession(), factory.getReplyToAddress()); } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java index db7356ed4..6fab17daa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java @@ -27,8 +27,10 @@ import javax.mail.internet.MimeMultipart; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration; import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective; +import freemarker.core.Environment; import freemarker.template.Template; import freemarker.template.TemplateException; @@ -47,7 +49,8 @@ public class FreemarkerEmailMessage { private static final Log log = LogFactory .getLog(FreemarkerEmailMessage.class); - private final Session session; + private final VitroRequest vreq; + private final Session mailSession; private final FreemarkerConfiguration config; private final List recipients = new ArrayList(); @@ -63,9 +66,10 @@ public class FreemarkerEmailMessage { /** * Package access - should only be created by the factory. */ - FreemarkerEmailMessage(FreemarkerConfiguration fConfig, Session session, - InternetAddress replyToAddress) { - this.session = session; + FreemarkerEmailMessage(VitroRequest vreq, FreemarkerConfiguration fConfig, + Session mailSession, InternetAddress replyToAddress) { + this.vreq = vreq; + this.mailSession = mailSession; this.replyToAddress = replyToAddress; this.config = fConfig; } @@ -141,7 +145,13 @@ public class FreemarkerEmailMessage { try { Template template = config.getTemplate(templateName); - template.process(bodyMap, new StringWriter()); + + Environment env = template.createProcessingEnvironment(bodyMap, + new StringWriter()); + env.setCustomAttribute("request", vreq); + env.setCustomAttribute("context", vreq.getSession() + .getServletContext()); + env.process(); } catch (TemplateException e) { log.error(e, e); } catch (IOException e) { @@ -151,7 +161,7 @@ public class FreemarkerEmailMessage { public boolean send() { try { - MimeMessage msg = new MimeMessage(session); + MimeMessage msg = new MimeMessage(mailSession); msg.setReplyTo(new Address[] { replyToAddress }); if (fromAddress == null) { @@ -199,11 +209,11 @@ public class FreemarkerEmailMessage { bodyPart.setContent(textBody, type); content.addBodyPart(bodyPart); } - - public String getReplyToAddress() { - return replyToAddress.getAddress(); - } - + + public String getReplyToAddress() { + return replyToAddress.getAddress(); + } + private T nonNull(T value, T defaultValue) { return (value == null) ? defaultValue : value; } From 96336cfbfd07b45a6b553da80ba9db16d0c2fb0e Mon Sep 17 00:00:00 2001 From: j2blake Date: Tue, 23 Apr 2013 17:28:46 -0400 Subject: [PATCH 02/18] Improve debug statements --- .../mannlib/vitro/webapp/i18n/I18nBundle.java | 13 ++++++++----- .../vitro/webapp/i18n/VitroResourceBundle.java | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java index 7ea5acc3d..44b930089 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java @@ -39,8 +39,9 @@ public class I18nBundle { public I18nBundle(String bundleName, ResourceBundle resources) { this(bundleName, resources, MESSAGE_KEY_NOT_FOUND); } - - private I18nBundle(String bundleName, ResourceBundle resources, String notFoundMessage) { + + private I18nBundle(String bundleName, ResourceBundle resources, + String notFoundMessage) { if (bundleName == null) { throw new IllegalArgumentException("bundleName may not be null"); } @@ -49,20 +50,22 @@ public class I18nBundle { } if (resources == null) { throw new NullPointerException("resources may not be null."); - }if (notFoundMessage == null) { + } + if (notFoundMessage == null) { throw new NullPointerException("notFoundMessage may not be null."); } this.bundleName = bundleName; this.resources = resources; this.notFoundMessage = notFoundMessage; } - + public String text(String key, Object... parameters) { - log.debug("Asking for '" + key + "' from bundle '" + bundleName + "'"); String textString; if (resources.containsKey(key)) { textString = resources.getString(key); + log.debug("In '" + bundleName + "', " + key + "='" + textString + + "')"); return formatString(textString, parameters); } else { String message = MessageFormat.format(notFoundMessage, bundleName, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java index c9b2b2acb..3d0640f30 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java @@ -60,7 +60,7 @@ public class VitroResourceBundle extends ResourceBundle { return new VitroResourceBundle(bundleName, ctx, appI18nPath, themeI18nPath, control); } catch (FileNotFoundException e) { - log.debug(e); + log.info(e.getMessage()); return null; } catch (Exception e) { log.warn(e, e); From c59076a19a2aa3bb19472184c134460b9d2b2bea Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 26 Apr 2013 23:44:17 -0400 Subject: [PATCH 03/18] Improve the look of the language selection flags --- .../freemarker/page/partials/languageSelector.ftl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/webapp/web/templates/freemarker/page/partials/languageSelector.ftl b/webapp/web/templates/freemarker/page/partials/languageSelector.ftl index cddb02a9f..2109f1912 100644 --- a/webapp/web/templates/freemarker/page/partials/languageSelector.ftl +++ b/webapp/web/templates/freemarker/page/partials/languageSelector.ftl @@ -9,14 +9,12 @@ <#-- This is included by identity.ftl --> <#if selectLocale??>
  • -
    - <#list selectLocale.locales as locale> - - <#if locale_has_next>| - -
    + <#list selectLocale.locales as locale> + + ${locale.label} + + <#if locale_has_next>| +
  • From bf2ed5c3399b26ee65c33a513250f3adfff1d060 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 26 Apr 2013 23:50:17 -0400 Subject: [PATCH 04/18] Proof of concept - Image upload --- .../freemarker/ImageUploadController.java | 77 +++++++++++++++---- .../freemarker/ImageUploadHelper.java | 42 +++++----- webapp/web/i18n/all.properties | 73 ++++++++++++++++++ webapp/web/i18n/all_es.properties | 43 +++++++++++ webapp/web/js/imageUpload/imageUploadUtils.js | 2 +- .../imageUpload/imageUpload-cropImage.ftl | 16 ++-- .../body/imageUpload/imageUpload-newImage.ftl | 26 ++++--- .../imageUpload/imageUpload-replaceImage.ftl | 28 ++++--- .../body/individual/individual-vitro.ftl | 4 + 9 files changed, 248 insertions(+), 63 deletions(-) create mode 100644 webapp/web/i18n/all.properties create mode 100644 webapp/web/i18n/all_es.properties diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java index 842a6201d..dcbe01f07 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java @@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil; /** @@ -48,6 +49,9 @@ public class ImageUploadController extends FreemarkerHttpServlet { private static final String ATTRIBUTE_REFERRING_PAGE = "ImageUploadController.referringPage"; + private static final String ERROR_CODE_UNRECOGNIZED_URI = "imageUpload.errorUnrecognizedURI"; + private static final String ERROR_CODE_NO_URI = "imageUpload.errorNoURI"; + /** Limit file size to 6 megabytes. */ public static final int MAXIMUM_FILE_SIZE = 6 * 1024 * 1024; @@ -97,6 +101,14 @@ public class ImageUploadController extends FreemarkerHttpServlet { private static final String URL_HERE = UrlBuilder.getUrl("/uploadImages"); + private static final String TEXT_BUNDLE = "imageUpload"; + private static final String TEXT_STRING_UPLOAD_TITLE = "upload_page_title"; + private static final String TEXT_STRING_UPLOAD_TITLE_WITH_NAME = "upload_page_title_with_name"; + private static final String TEXT_STRING_REPLACE_TITLE = "replace_page_title"; + private static final String TEXT_STRING_REPLACE_TITLE_WITH_NAME = "replace_page_title_with_name"; + private static final String TEXT_STRING_CROP_TITLE = "crop_page_title"; + private static final String TEXT_STRING_CROP_TITLE_WITH_NAME = "crop_page_title_with_name"; + private FileStorage fileStorage; /** @@ -218,7 +230,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { } } catch (UserMistakeException e) { // Can't find the entity? Complain. - return showAddImagePageWithError(vreq, null, e.getMessage()); + return showAddImagePageWithError(vreq, null, e.formatMessage(vreq)); } catch (Exception e) { // We weren't expecting this - log it, and apologize to the user. return new ExceptionResponseValues(e); @@ -274,7 +286,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return showCropImagePage(vreq, entity, fileInfo.getBytestreamAliasUrl(), size); } catch (UserMistakeException e) { - return showErrorMessage(vreq, entity, e.getMessage()); + return showErrorMessage(vreq, entity, e.formatMessage(vreq)); } } @@ -284,6 +296,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private ResponseValues showErrorMessage(VitroRequest vreq, Individual entity, String message) { + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri( vreq.getFullWebappDaoFactory(), entity); if (imageInfo == null) { @@ -313,7 +326,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return showExitPage(vreq, entity); } catch (UserMistakeException e) { - return showErrorMessage(vreq, entity, e.getMessage()); + return showErrorMessage(vreq, entity, e.formatMessage(vreq)); } } @@ -350,15 +363,14 @@ public class ImageUploadController extends FreemarkerHttpServlet { throws UserMistakeException { String entityUri = vreq.getParameter(PARAMETER_ENTITY_URI); if (entityUri == null) { - throw new UserMistakeException("No entity URI was provided"); + throw new UserMistakeException(ERROR_CODE_NO_URI); } Individual entity = vreq.getFullWebappDaoFactory().getIndividualDao() .getIndividualByURI(entityUri); if (entity == null) { - throw new UserMistakeException( - "This URI is not recognized as belonging to anyone: '" - + entityUri + "'"); + throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_URI, + entityUri); } return entity; } @@ -416,7 +428,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_THUMBNAIL_URL, placeholderUrl); rv.put(BODY_FORM_ACTION, formAction); rv.put(BODY_CANCEL_URL, cancelUrl); - rv.put(BODY_TITLE, "Upload image" + forName(entity)); + rv.put(BODY_TITLE, figureUploadPageTitle(vreq, entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_THUMBNAIL_HEIGHT, THUMBNAIL_HEIGHT); rv.put(BODY_THUMBNAIL_WIDTH, THUMBNAIL_WIDTH); @@ -442,7 +454,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT)); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); - rv.put(BODY_TITLE, "Replace image" + forName(entity)); + rv.put(BODY_TITLE, figureReplacePageTitle(vreq, entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_THUMBNAIL_HEIGHT, THUMBNAIL_HEIGHT); rv.put(BODY_THUMBNAIL_WIDTH, THUMBNAIL_WIDTH); @@ -472,7 +484,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); - rv.put(BODY_TITLE, "Crop Photo" + forName(entity)); + rv.put(BODY_TITLE, figureCropPageTitle(vreq, entity)); return rv; } @@ -522,24 +534,59 @@ public class ImageUploadController extends FreemarkerHttpServlet { } /** - * Format the entity's name for display as part of the page title. + * Format the title for the Upload page. */ - private String forName(Individual entity) { + private String figureUploadPageTitle(HttpServletRequest req, + Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_UPLOAD_TITLE, + TEXT_STRING_UPLOAD_TITLE_WITH_NAME); + } + + /** + * Format the title for the Replace page. + */ + private String figureReplacePageTitle(HttpServletRequest req, + Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_REPLACE_TITLE, + TEXT_STRING_REPLACE_TITLE_WITH_NAME); + } + + /** + * Format the title for the Crop page. + */ + private String figureCropPageTitle(HttpServletRequest req, Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_CROP_TITLE, + TEXT_STRING_CROP_TITLE_WITH_NAME); + } + + /** + * Format one of two page titles, depending on whether the entity has a + * name. + */ + private String figurePageTitle(HttpServletRequest req, Individual entity, + String noNameTitleKey, String nameTitleKey) { if (entity != null) { String name = entity.getName(); if (name != null) { - return " for " + name; + return I18n.text(req, TEXT_BUNDLE, nameTitleKey, name); } } - return ""; + return I18n.text(req, TEXT_BUNDLE, noNameTitleKey); } /** * Holds an error message to use as a complaint to the user. */ static class UserMistakeException extends Exception { - UserMistakeException(String message) { + private final Object[] parameters; + + UserMistakeException(String message, Object... parameters) { super(message); + this.parameters = parameters; + } + + public String formatMessage(HttpServletRequest req) { + return I18n.text(req, getMessage(), parameters); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java index 656a0f0a7..e0052b7bd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java @@ -49,6 +49,18 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServ public class ImageUploadHelper { private static final Log log = LogFactory.getLog(ImageUploadHelper.class); + /* + * Keys to text strings for error messages. + */ + private static final String ERROR_CODE_NO_IMAGE_TO_CROP = "imageUpload.errorNoImageForCropping"; + private static final String ERROR_CODE_IMAGE_TOO_SMALL = "imageUpload.errorImageTooSmall"; + private static final String ERROR_CODE_UNKNOWN = "imageUpload.errorUnknown"; + private static final String ERROR_CODE_FILE_TOO_BIG = "imageUpload.errorFileTooBig"; + private static final String ERROR_CODE_UNRECOGNIZED_FILE_TYPE = "imageUpload.errorUnrecognizedFileType"; + private static final String ERROR_CODE_NO_PHOTO_SELECTED = "imageUpload.errorNoPhotoSelected"; + private static final String ERROR_CODE_BAD_MULTIPART_REQUEST = "imageUpload.errorBadMultipartRequest"; + private static final String ERROR_CODE_FORM_FIELD_MISSING = "imageUpload.errorFormFieldMissing"; + /** * When they upload a new image, store it as this session attribute until * we're ready to attach it to the Individual. @@ -127,35 +139,31 @@ public class ImageUploadHelper { Object exception = request.getAttribute(FILE_UPLOAD_EXCEPTION); if (exception != null) { int limit = MAXIMUM_FILE_SIZE / (1024 * 1024); - throw new UserMistakeException( - "Please upload an image smaller than " + limit - + " megabytes"); + throw new UserMistakeException(ERROR_CODE_FILE_TOO_BIG, limit); } Map> map = (Map>) request .getAttribute(FILE_ITEM_MAP); if (map == null) { - throw new IllegalStateException("Failed to parse the " - + "multi-part request for uploading an image."); + throw new IllegalStateException(ERROR_CODE_BAD_MULTIPART_REQUEST); } List list = map.get(PARAMETER_UPLOADED_FILE); if ((list == null) || list.isEmpty()) { - throw new UserMistakeException("The form did not contain a '" - + PARAMETER_UPLOADED_FILE + "' field."); + throw new UserMistakeException(ERROR_CODE_FORM_FIELD_MISSING, + PARAMETER_UPLOADED_FILE); } FileItem file = list.get(0); if (file.getSize() == 0) { - throw new UserMistakeException("Please browse and select a photo."); + throw new UserMistakeException(ERROR_CODE_NO_PHOTO_SELECTED); } String filename = getSimpleFilename(file); String mimeType = getMimeType(file); if (!RECOGNIZED_FILE_TYPES.containsValue(mimeType)) { log.debug("Unrecognized MIME type: '" + mimeType + "'"); - throw new UserMistakeException("'" + filename - + "' is not a recognized image file type. " - + "Please upload JPEG, GIF, or PNG files only."); + throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_FILE_TYPE, + filename); } return file; @@ -221,10 +229,8 @@ public class ImageUploadHelper { if ((size.height < THUMBNAIL_HEIGHT) || (size.width < THUMBNAIL_WIDTH)) { - throw new UserMistakeException( - "The uploaded image should be at least " - + THUMBNAIL_HEIGHT + " pixels high and " - + THUMBNAIL_WIDTH + " pixels wide."); + throw new UserMistakeException(ERROR_CODE_IMAGE_TOO_SMALL, + THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH); } return size; @@ -237,8 +243,7 @@ public class ImageUploadHelper { throw e; } catch (Exception e) { log.warn("Unexpected exception in image handling", e); - throw new UserMistakeException("Sorry, we were unable to process " - + "the photo you provided. Please try another photo."); + throw new UserMistakeException(ERROR_CODE_UNKNOWN); } finally { if (source != null) { try { @@ -261,8 +266,7 @@ public class ImageUploadHelper { ATTRIBUTE_TEMP_FILE); if (fileInfo == null) { - throw new UserMistakeException( - "There is no image file to be cropped."); + throw new UserMistakeException(ERROR_CODE_NO_IMAGE_TO_CROP); } return fileInfo; diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties new file mode 100644 index 000000000..ce912c828 --- /dev/null +++ b/webapp/web/i18n/all.properties @@ -0,0 +1,73 @@ +# +# Text strings for the controllers and templates +# +# Default (English) +# +save_changes = Save changes +cancel_link = Cancel +cancel_title = cancel +required_fields = required fields +or = or +alt_error_alert = Error alert icon +alt_confirmation = Confirmation icon + +email_address = Email address +first_name = First name +last_name = Last name +roles = Roles +status = Status + +ascending_order = ascending order +descending_order = descending order +select_one = Select one + +type_more_characters = type more characters +no_match = no match + +request_failed = Request failed. Please contact your system administrator. + +# +# Image upload pages +# +upload_page_title = Upload image +upload_page_title_with_name = Upload image for {0} +upload_heading = Photo Upload + +replace_page_title = Replace image +replace_page_title_with_name = Replace image for {0} + +crop_page_title = Crop image +crop_page_title_with_name = Crop image for {0} + +current_photo = Current Photo +upload_photo = Upload a photo +replace_photo = Replace Photo +photo_types = (JPEG, GIF or PNG) +maximum_file_size = Maximum file size: {0} megabytes +minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels + +cropping_caption = Your profile photo will look like the image below. +cropping_note = To make adjustments, you can drag around and resize the photo to the right. \ + When you are happy with your photo click the "Save Photo" button. + +alt_thumbnail_photo = Individual photo +alt_image_to_crop = Image to be cropped +alt_preview_crop = Preview of photo cropped + +delete_link = Delete photo +submit_upload = Upload photo +submit_save = Save photo + +confirm_delete = Are you sure you want to delete this photo? + +imageUpload.errorNoURI = No entity URI was provided +imageUpload.errorUnrecognizedURI = This URI is not recognized as belonging to anyone: ''{0}'' +imageUpload.errorNoImageForCropping = There is no image file to be cropped. +imageUpload.errorImageTooSmall = The uploaded image should be at least {0} pixels high and {1} pixels wide. +imageUpload.errorUnknown = Sorry, we were unable to process the photo you provided. Please try another photo. +imageUpload.errorFileTooBig = Please upload an image smaller than {0} megabytes. +imageUpload.errorUnrecognizedFileType = ''{0}'' is not a recognized image file type. Please upload JPEG, GIF, or PNG files only. +imageUpload.errorNoPhotoSelected = Please browse and select a photo. +imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image. +imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." + diff --git a/webapp/web/i18n/all_es.properties b/webapp/web/i18n/all_es.properties new file mode 100644 index 000000000..ecb295fec --- /dev/null +++ b/webapp/web/i18n/all_es.properties @@ -0,0 +1,43 @@ +# +# Text strings for the controllers and templates +# +# Spanish +# +cancel_link = Cancelar +or = o +alt_error_alert = Icono de alerta con error + +# +# Image upload pages +# +upload_page_title = Subir foto +upload_page_title_with_name = Subir imagen para {0} +upload_heading = Subir foto + +replace_page_title = Reemplazar imagen +replace_page_title_with_name = Cambie la imagen por {0} + +crop_page_title = Recortar imagen +crop_page_title_with_name = Recorte imagen para {0} + +current_photo = Foto actual +upload_photo = Suba foto +replace_photo = Reemplace foto +photo_types = (JPEG, GIF, o PNG) +maximum_file_size = Tamaño máximo de archivo: {0} megabytes +minimum_image_dimensions = Dimensiones mínimas de imagen: {0} x {1} pixels + +cropping_caption = La foto de tu perfil se verá como la imagen de abajo. +cropping_note = Para realizar ajustes, arrastre alrededor y cambie el tamaño de la foto de la derecha. \ + Cuando esté satisfecho con su foto, haga clic en el botón "Guardar foto". + +alt_thumbnail_photo = Foto de individuo +alt_image_to_crop = Imagen que desea recortar +alt_preview_crop = Vista previa de la foto recortada + +delete_link = Borrar foto +submit_upload = Subir foto +submit_save = Guardar foto + +confirm_delete = ¿Seguro que quiere borrar esta foto? + diff --git a/webapp/web/js/imageUpload/imageUploadUtils.js b/webapp/web/js/imageUpload/imageUploadUtils.js index 0364689a1..2a2775d1c 100644 --- a/webapp/web/js/imageUpload/imageUploadUtils.js +++ b/webapp/web/js/imageUpload/imageUploadUtils.js @@ -4,7 +4,7 @@ $(document).ready(function(){ // Confirmation alert for photo deletion in image upload and individual templates $('#photoUploadDefaultImage a.thumbnail, a.delete-mainImage').click(function(){ - var answer = confirm('Are you sure you want to delete this photo?'); + var answer = confirm(i18n_confirmDelete); return answer; }); }); \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl index 9f6f94ad0..bd8d7b5b0 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl @@ -21,20 +21,22 @@ ${stylesheets.add(' -

    Photo Upload

    +

    ${i18n.upload_heading}

    -

    Your profile photo will look like the image below.

    +

    ${i18n.cropping_caption}

    - Image to be cropped + ${i18n.alt_image_to_crop}
    -

    To make adjustments, you can drag around and resize the photo to the right. When you are happy with your photo click the "Save Photo" button.

    +

    ${i18n.cropping_note}

    @@ -43,15 +45,15 @@ ${stylesheets.add(' - + - or Cancel + ${i18n.or} ${i18n.cancel_link}
    - Preview of photo cropped + ${i18n.alt_preview_crop}
    diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl index 675b63920..cf9a6b204 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl @@ -7,29 +7,35 @@ ${scripts.add(' diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl index d8850d188..cc5a9b7bd 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl @@ -7,30 +7,36 @@ ${scripts.add(' diff --git a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl index 8e13dd2d9..12bc8f92c 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl @@ -77,3 +77,7 @@ ${headScripts.add('', '')} + + From 8f1f084c5b0f57d460058fb65e1be8504260995b Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 26 Apr 2013 23:58:50 -0400 Subject: [PATCH 05/18] Proof of concept - User accounts --- .../controller/AbstractPageHandler.java | 7 +- .../admin/UserAccountsAddPageStrategy.java | 2 +- .../accounts/admin/UserAccountsDeleter.java | 11 +- .../accounts/admin/UserAccountsEditPage.java | 7 +- .../user/UserAccountsCreatePasswordPage.java | 8 +- .../UserAccountsFirstTimeExternalPage.java | 9 +- ...AccountsFirstTimeExternalPageStrategy.java | 2 +- .../UserAccountsMyAccountPageStrategy.java | 2 +- .../user/UserAccountsPasswordBasePage.java | 8 +- .../user/UserAccountsResetPasswordPage.java | 9 +- .../user/UserAccountsUserController.java | 13 +- webapp/web/i18n/all.properties | 145 ++++++++++++++++++ .../web/i18n/files/accountCreatedEmail.html | 39 +++++ webapp/web/i18n/files/accountCreatedEmail.txt | 17 ++ .../accountCreatedExternalOnlyEmail.html | 22 +++ .../files/accountCreatedExternalOnlyEmail.txt | 9 ++ .../web/i18n/files/accountEmailChanged.html | 19 +++ webapp/web/i18n/files/accountEmailChanged.txt | 6 + .../i18n/files/accountFirstTimeExternal.html | 22 +++ .../i18n/files/accountFirstTimeExternal.txt | 8 + .../web/i18n/files/passwordCreatedEmail.html | 22 +++ .../web/i18n/files/passwordCreatedEmail.txt | 8 + .../i18n/files/passwordRequestPending.html | 34 ++++ .../web/i18n/files/passwordRequestPending.txt | 16 ++ .../web/i18n/files/passwordResetComplete.html | 22 +++ .../web/i18n/files/passwordResetComplete.txt | 8 + .../web/i18n/files/passwordResetPending.html | 34 ++++ .../web/i18n/files/passwordResetPending.txt | 16 ++ webapp/web/js/account/accountUtils.js | 2 +- .../userAccounts-acctCreatedEmail.ftl | 73 ++------- ...rAccounts-acctCreatedExternalOnlyEmail.ftl | 46 ++---- .../body/accounts/userAccounts-add.ftl | 89 ++++------- .../userAccounts-associateProfilePanel.ftl | 26 ++-- .../userAccounts-confirmEmailChangedEmail.ftl | 43 ++---- .../accounts/userAccounts-createPassword.ftl | 49 +++--- .../body/accounts/userAccounts-edit.ftl | 91 +++++------ .../userAccounts-firstTimeExternal.ftl | 54 +++---- .../userAccounts-firstTimeExternalEmail.ftl | 46 ++---- .../body/accounts/userAccounts-list.ftl | 86 +++++------ .../body/accounts/userAccounts-myAccount.ftl | 82 +++++----- .../accounts/userAccounts-myProxiesPanel.ftl | 18 ++- .../userAccounts-passwordCreatedEmail.ftl | 46 ++---- ...serAccounts-passwordResetCompleteEmail.ftl | 46 ++---- ...userAccounts-passwordResetPendingEmail.ftl | 66 ++------ .../accounts/userAccounts-resetPassword.ftl | 48 +++--- 45 files changed, 826 insertions(+), 610 deletions(-) create mode 100644 webapp/web/i18n/files/accountCreatedEmail.html create mode 100644 webapp/web/i18n/files/accountCreatedEmail.txt create mode 100644 webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html create mode 100644 webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt create mode 100644 webapp/web/i18n/files/accountEmailChanged.html create mode 100644 webapp/web/i18n/files/accountEmailChanged.txt create mode 100644 webapp/web/i18n/files/accountFirstTimeExternal.html create mode 100644 webapp/web/i18n/files/accountFirstTimeExternal.txt create mode 100644 webapp/web/i18n/files/passwordCreatedEmail.html create mode 100644 webapp/web/i18n/files/passwordCreatedEmail.txt create mode 100644 webapp/web/i18n/files/passwordRequestPending.html create mode 100644 webapp/web/i18n/files/passwordRequestPending.txt create mode 100644 webapp/web/i18n/files/passwordResetComplete.html create mode 100644 webapp/web/i18n/files/passwordResetComplete.txt create mode 100644 webapp/web/i18n/files/passwordResetPending.html create mode 100644 webapp/web/i18n/files/passwordResetPending.txt diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java index 3cb19c96d..6aab54794 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java @@ -25,6 +25,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; +import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle; /** * A base class with some utility routines for page handler (created by @@ -39,6 +41,7 @@ public abstract class AbstractPageHandler { private static final Log log = LogFactory.getLog(AbstractPageHandler.class); protected final VitroRequest vreq; + protected final I18nBundle i18n; protected final ServletContext ctx; protected final OntModel userAccountsModel; protected final OntModel unionModel; @@ -50,6 +53,7 @@ public abstract class AbstractPageHandler { protected AbstractPageHandler(VitroRequest vreq) { this.vreq = vreq; + this.i18n = I18n.bundle(vreq); this.ctx = vreq.getSession().getServletContext(); OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx); @@ -154,7 +158,8 @@ public abstract class AbstractPageHandler { private static final String ATTRIBUTE = Message.class.getName(); public static void setMessage(HttpServletRequest req, Message message) { - log.debug("Added message to session: " + message.getMessageInfoMap()); + log.debug("Added message to session: " + + message.getMessageInfoMap()); req.getSession().setAttribute(ATTRIBUTE, message); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java index 19b135bc3..caa52e38a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java @@ -103,7 +103,7 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage { FreemarkerEmailMessage email = FreemarkerEmailFactory .createNewMessage(vreq); email.addRecipient(TO, page.getAddedAccount().getEmailAddress()); - email.setSubject("Your VIVO account has been created."); + email.setSubject(i18n.text("account_created_subject", getSiteName())); if (page.isExternalAuthOnly()) { email.setTemplate(EMAIL_TEMPLATE_NO_PASSWORD); } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java index b8484715a..012b9abc6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin; +import static edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController.getBogusStandardMessage; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -15,7 +17,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageRoot import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage; -import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; /** @@ -51,7 +52,7 @@ public class UserAccountsDeleter extends UserAccountsPage { UserAccount loggedInAccount = LoginStatusBean.getCurrentUser(vreq); if (loggedInAccount == null) { log.warn("Trying to delete accounts while not logged in!"); - bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE; + bogusMessage = getBogusStandardMessage(vreq); return; } @@ -61,14 +62,14 @@ public class UserAccountsDeleter extends UserAccountsPage { if (u == null) { log.warn("Delete account for '" + uri + "' is bogus: no such user"); - bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE; + bogusMessage = getBogusStandardMessage(vreq); return; } if (u.getUri().equals(loggedInAccount.getUri())) { log.warn("'" + u.getUri() + "' is trying to delete his own account."); - bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE; + bogusMessage = getBogusStandardMessage(vreq); return; } @@ -78,7 +79,7 @@ public class UserAccountsDeleter extends UserAccountsPage { log.warn("Attempting to delete the root account, " + "but not authorized. Logged in as " + LoginStatusBean.getCurrentUser(vreq)); - bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE; + bogusMessage = getBogusStandardMessage(vreq); return; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java index 0b2e81045..f13c2eab3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin; +import static edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController.getBogusStandardMessage; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -20,7 +22,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage; -import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; @@ -116,7 +117,7 @@ public class UserAccountsEditPage extends UserAccountsPage { if (userAccount == null) { log.warn("Edit account for '" + userUri + "' is bogus: no such user"); - bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE; + bogusMessage = getBogusStandardMessage(vreq); return; } if (userAccount.isRootUser()) { @@ -125,7 +126,7 @@ public class UserAccountsEditPage extends UserAccountsPage { log.warn("User is attempting to edit the root account, " + "but is not authorized to do so. Logged in as: " + LoginStatusBean.getCurrentUser(vreq)); - bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE; + bogusMessage = getBogusStandardMessage(vreq); return; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java index b227a0728..3b6585e72 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java @@ -46,14 +46,12 @@ public class UserAccountsCreatePasswordPage extends @Override protected String alreadyLoggedInMessage(String currentUserEmail) { - return "You may not activate the account for " + userEmail - + " while you are logged in as " + currentUserEmail - + ". Please log out and try again."; + return i18n.text("cant_activate_while_logged_in", userEmail, currentUserEmail); } @Override protected String passwordChangeNotPendingMessage() { - return "The account for " + userEmail + " has already been activated."; + return i18n.text("account_already_activated", userEmail); } @Override @@ -69,7 +67,7 @@ public class UserAccountsCreatePasswordPage extends FreemarkerEmailMessage email = FreemarkerEmailFactory .createNewMessage(vreq); email.addRecipient(TO, userAccount.getEmailAddress()); - email.setSubject("Password successfully created."); + email.setSubject(i18n.text("password_created_subject", getSiteName())); email.setTemplate(EMAIL_TEMPLATE); email.setBodyMap(body); email.processTemplate(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java index 78ea1c7ec..9ac36f700 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java @@ -115,18 +115,17 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage { private void validateExternalAuthId() { if (externalAuthId.isEmpty()) { - bogusMessage = "Login failed - External ID is not found."; + bogusMessage = i18n.text("external_id_not_provided"); return; } if (null != userAccountsDao .getUserAccountByExternalAuthId(externalAuthId)) { - bogusMessage = "User account already exists for '" + externalAuthId - + "'"; + bogusMessage = i18n.text("external_id_already_in_use", + externalAuthId); return; } if (!Authenticator.getInstance(vreq).isUserPermittedToLogin(null)) { - bogusMessage = "User logins are temporarily disabled " - + "while the system is being maintained."; + bogusMessage = i18n.text("logins_disabled_for_maintenance"); return; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPageStrategy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPageStrategy.java index 79ee65e1d..ca1423ad3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPageStrategy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPageStrategy.java @@ -73,7 +73,7 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends FreemarkerEmailMessage email = FreemarkerEmailFactory .createNewMessage(vreq); email.addRecipient(TO, ua.getEmailAddress()); - email.setSubject("Your VIVO account has been created."); + email.setSubject(i18n.text("account_created_subject", getSiteName())); email.setTemplate(EMAIL_TEMPLATE); email.setBodyMap(body); email.processTemplate(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java index 6d72a941e..b16094631 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java @@ -178,7 +178,7 @@ public abstract class UserAccountsMyAccountPageStrategy extends FreemarkerEmailMessage email = FreemarkerEmailFactory .createNewMessage(vreq); email.addRecipient(TO, page.getUserAccount().getEmailAddress()); - email.setSubject("Your VIVO email account has been changed."); + email.setSubject(i18n.text("email_changed_subject")); email.setTemplate(EMAIL_TEMPLATE); email.setBodyMap(body); email.processTemplate(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java index 1764c9e7a..78e78ce3f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java @@ -23,8 +23,6 @@ public abstract class UserAccountsPasswordBasePage extends UserAccountsPage { private static final Log log = LogFactory .getLog(UserAccountsPasswordBasePage.class); - public static final String BOGUS_MESSAGE_NO_SUCH_ACCOUNT = "The account you are trying to set a password on is no longer available. Please contact your system administrator if you think this is an error."; - private static final String PARAMETER_SUBMIT = "submit"; private static final String PARAMETER_USER = "user"; private static final String PARAMETER_KEY = "key"; @@ -79,7 +77,7 @@ public abstract class UserAccountsPasswordBasePage extends UserAccountsPage { if (userAccount == null) { log.warn("Password request for '" + userEmail + "' is bogus: no such user"); - bogusMessage = BOGUS_MESSAGE_NO_SUCH_ACCOUNT; + bogusMessage = i18n.text("account_no_longer_exists"); return; } @@ -170,9 +168,9 @@ public abstract class UserAccountsPasswordBasePage extends UserAccountsPage { public String getSuccessMessage() { if (loggedIn) { - return "Your password has been saved."; + return i18n.text("password_saved"); } else { - return "Your password has been saved. Please log in."; + return i18n.text("password_saved_please_login"); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java index e9b07ba36..9a42ab8c7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java @@ -46,14 +46,13 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage @Override protected String alreadyLoggedInMessage(String currentUserEmail) { - return "You may not reset the password for " + userEmail - + " while you are logged in as " + currentUserEmail - + ". Please log out and try again."; + return i18n.text("cant_change_password_while_logged_in", userEmail, + currentUserEmail); } @Override protected String passwordChangeNotPendingMessage() { - return "The password for " + userEmail + " has already been reset."; + return i18n.text("password_change_not_pending", userEmail); } @Override @@ -69,7 +68,7 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage FreemarkerEmailMessage email = FreemarkerEmailFactory .createNewMessage(vreq); email.addRecipient(TO, userAccount.getEmailAddress()); - email.setSubject("Password changed."); + email.setSubject(i18n.text("password_changed_subject")); email.setTemplate(EMAIL_TEMPLATE); email.setBodyMap(body); email.processTemplate(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java index e2f7a47e6..eb2d175fe 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java @@ -4,6 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.user; import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL; +import javax.servlet.http.HttpServletRequest; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,6 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; /** * Parcel out the different actions required of the UserAccounts GUI. @@ -26,8 +29,6 @@ public class UserAccountsUserController extends FreemarkerHttpServlet { private static final Log log = LogFactory .getLog(UserAccountsUserController.class); - public static final String BOGUS_STANDARD_MESSAGE = "Request failed. Please contact your system administrator."; - private static final String ACTION_CREATE_PASSWORD = "/createPassword"; private static final String ACTION_RESET_PASSWORD = "/resetPassword"; private static final String ACTION_MY_ACCOUNT = "/myAccount"; @@ -116,7 +117,7 @@ public class UserAccountsUserController extends FreemarkerHttpServlet { return showLoginRedirection(vreq, page.getAfterLoginUrl()); } catch (LoginNotPermitted e) { // This should have been anticipated by the page. - return showHomePage(vreq, BOGUS_STANDARD_MESSAGE); + return showHomePage(vreq, getBogusStandardMessage(vreq)); } } else { return page.showPage(); @@ -124,7 +125,7 @@ public class UserAccountsUserController extends FreemarkerHttpServlet { } private ResponseValues handleInvalidRequest(VitroRequest vreq) { - return showHomePage(vreq, BOGUS_STANDARD_MESSAGE); + return showHomePage(vreq, getBogusStandardMessage(vreq)); } private ResponseValues showHomePage(VitroRequest vreq, String message) { @@ -159,4 +160,8 @@ public class UserAccountsUserController extends FreemarkerHttpServlet { } return uri; } + + public static String getBogusStandardMessage(HttpServletRequest req) { + return I18n.bundle(req).text("request_failed"); + } } diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties index ce912c828..ad5ec0618 100644 --- a/webapp/web/i18n/all.properties +++ b/webapp/web/i18n/all.properties @@ -71,3 +71,148 @@ imageUpload.errorNoPhotoSelected = Please browse and select a photo. imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image. imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." +# +# User Accounts pages +# +account_management = Account Management +user_accounts_link = User accounts +user_accounts_title = user accounts + +login_count = Login count +last_login = Last Login + +add_new_account = Add new account +edit_account = Edit account +external_auth_only = Externally Authenticated Only +reset_password = Reset password +reset_password_note = Note: Instructions for resetting the password will \ + be emailed to the address entered above. The password will not \ + be reset until the user follows the link provided in this email. +new_password = New password +confirm_password = Confirm new password +minimum_password_length = Minimum of {0} characters in length. +leave_password_unchanged = Leaving this blank means that the password will not be changed. +confirm_initial_password = Confirm initial password + +new_account_1 = A new account for +new_account_2 = was successfully created. +new_account_title = new account +new_account_notification = A notification email has been sent to {0} \ + with instructions for activating the account and creating a password. +updated_account_1 = The account for +updated_account_2 = has been updated. +updated_account_title = updated account +updated_account_notification = A confirmation email has been sent to {0} \ + with instructions for resetting a password. \ + The password will not be reset until the user follows the link provided in this email. +deleted_accounts = Deleted {0} {0, choice, 0#accounts |1#account |1 + + {1} + + +

    + {2} {3} +

    + +

    + Congratulations! +

    + +

    + We have created your new account on {0}, associated with {4}. +

    + +

    + If you did not request this new account you can safely ignore this email. + This request will expire if not acted upon for 30 days. +

    + +

    + Click the link below to create your password for your new account using our secure server. +

    + +

    + {5} +

    + +

    + If the link above doesn't work, you can copy and paste the link directly into your browser's address bar. +

    + +

    + Thanks! +

    + + diff --git a/webapp/web/i18n/files/accountCreatedEmail.txt b/webapp/web/i18n/files/accountCreatedEmail.txt new file mode 100644 index 000000000..4dcd900c8 --- /dev/null +++ b/webapp/web/i18n/files/accountCreatedEmail.txt @@ -0,0 +1,17 @@ +{2} {3} + +Congratulations! + +We have created your new account on {0}, +associated with {4}. + +If you did not request this new account you can safely ignore this email. +This request will expire if not acted upon for 30 days. + +Paste the link below into your browser's address bar to create your password +for your new account using our secure server. + +{5} + +Thanks! + diff --git a/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html new file mode 100644 index 000000000..164bf87ae --- /dev/null +++ b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html @@ -0,0 +1,22 @@ + + + ${1} + + +

    + ${2} ${3} +

    + +

    + Congratulations! +

    + +

    + We have created your new VIVO account associated with ${4}. +

    + +

    + Thanks! +

    + + diff --git a/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt new file mode 100644 index 000000000..c55cb3f9a --- /dev/null +++ b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt @@ -0,0 +1,9 @@ +${2} ${3} + +Congratulations! + +We have created your new VIVO account associated with +${4}. + +Thanks! + diff --git a/webapp/web/i18n/files/accountEmailChanged.html b/webapp/web/i18n/files/accountEmailChanged.html new file mode 100644 index 000000000..5a2e51e50 --- /dev/null +++ b/webapp/web/i18n/files/accountEmailChanged.html @@ -0,0 +1,19 @@ + + + {1} + + +

    + Hi, {2} ${3} +

    + +

    + You recently changed the email address associated with + ${2} ${3} +

    + +

    + Thank you. +

    + + diff --git a/webapp/web/i18n/files/accountEmailChanged.txt b/webapp/web/i18n/files/accountEmailChanged.txt new file mode 100644 index 000000000..5f560dca1 --- /dev/null +++ b/webapp/web/i18n/files/accountEmailChanged.txt @@ -0,0 +1,6 @@ +Hi, {2} {3} + +You recently changed the email address associated with +{2} {3} + +Thank you. diff --git a/webapp/web/i18n/files/accountFirstTimeExternal.html b/webapp/web/i18n/files/accountFirstTimeExternal.html new file mode 100644 index 000000000..61dca7f3c --- /dev/null +++ b/webapp/web/i18n/files/accountFirstTimeExternal.html @@ -0,0 +1,22 @@ + + + {1} + + +

    + {2} {3} +

    + +

    + Congratulations! +

    + +

    + We have created your new {0} account associated with {4}. +

    + +

    + Thanks! +

    + + diff --git a/webapp/web/i18n/files/accountFirstTimeExternal.txt b/webapp/web/i18n/files/accountFirstTimeExternal.txt new file mode 100644 index 000000000..1cb60552b --- /dev/null +++ b/webapp/web/i18n/files/accountFirstTimeExternal.txt @@ -0,0 +1,8 @@ +{2} {3} + +Congratulations! + +We have created your new {0} account associated with +{4} + +Thanks! diff --git a/webapp/web/i18n/files/passwordCreatedEmail.html b/webapp/web/i18n/files/passwordCreatedEmail.html new file mode 100644 index 000000000..15cf8bb0d --- /dev/null +++ b/webapp/web/i18n/files/passwordCreatedEmail.html @@ -0,0 +1,22 @@ + + + {1} + + +

    + {2} {3} +

    + +

    + Password successfully created. +

    + +

    + Your new password associated with {4} has been created. +

    + +

    + Thank you. +

    + + diff --git a/webapp/web/i18n/files/passwordCreatedEmail.txt b/webapp/web/i18n/files/passwordCreatedEmail.txt new file mode 100644 index 000000000..dbd9e9da0 --- /dev/null +++ b/webapp/web/i18n/files/passwordCreatedEmail.txt @@ -0,0 +1,8 @@ +{2} {3} + +Password successfully created. + +Your new password associated with {4} +has been created. + +Thank you. diff --git a/webapp/web/i18n/files/passwordRequestPending.html b/webapp/web/i18n/files/passwordRequestPending.html new file mode 100644 index 000000000..bd20cb392 --- /dev/null +++ b/webapp/web/i18n/files/passwordRequestPending.html @@ -0,0 +1,34 @@ + + + {1} + + +

    + Dear {2} {3}: +

    + +

    + We have received a request to reset the password for your {0} account ({4}). +

    + +

    + Please follow the instructions below to proceed with your password reset. +

    + +

    + If you did not request this new account you can safely ignore this email. + This request will expire if not acted upon within 30 days. +

    + +

    + Click on the link below or paste it into your browser's address bar to reset your password + using our secure server. +

    + +

    + {5} +

    + +

    Thank you!

    + + diff --git a/webapp/web/i18n/files/passwordRequestPending.txt b/webapp/web/i18n/files/passwordRequestPending.txt new file mode 100644 index 000000000..e8c92b5f2 --- /dev/null +++ b/webapp/web/i18n/files/passwordRequestPending.txt @@ -0,0 +1,16 @@ +Dear {2} {3}: + +We have received a request to reset the password for your {0} account +({4}). + +Please follow the instructions below to proceed with your password reset. + +If you did not request this new account you can safely ignore this email. +This request will expire if not acted upon within 30 days. + +Paste the link below into your browser's address bar to reset your password +using our secure server. + +{5} + +Thank you! diff --git a/webapp/web/i18n/files/passwordResetComplete.html b/webapp/web/i18n/files/passwordResetComplete.html new file mode 100644 index 000000000..bfa756f15 --- /dev/null +++ b/webapp/web/i18n/files/passwordResetComplete.html @@ -0,0 +1,22 @@ + + + {1} + + +

    + {2} {3} +

    + +

    + Password successfully changed. +

    + +

    + Your new password associated with {4} has been changed. +

    + +

    + Thank you. +

    + + diff --git a/webapp/web/i18n/files/passwordResetComplete.txt b/webapp/web/i18n/files/passwordResetComplete.txt new file mode 100644 index 000000000..99503085c --- /dev/null +++ b/webapp/web/i18n/files/passwordResetComplete.txt @@ -0,0 +1,8 @@ +{2} {3} + +Password successfully changed. + +Your new password associated with {4} +has been changed. + +Thank you. diff --git a/webapp/web/i18n/files/passwordResetPending.html b/webapp/web/i18n/files/passwordResetPending.html new file mode 100644 index 000000000..bd20cb392 --- /dev/null +++ b/webapp/web/i18n/files/passwordResetPending.html @@ -0,0 +1,34 @@ + + + {1} + + +

    + Dear {2} {3}: +

    + +

    + We have received a request to reset the password for your {0} account ({4}). +

    + +

    + Please follow the instructions below to proceed with your password reset. +

    + +

    + If you did not request this new account you can safely ignore this email. + This request will expire if not acted upon within 30 days. +

    + +

    + Click on the link below or paste it into your browser's address bar to reset your password + using our secure server. +

    + +

    + {5} +

    + +

    Thank you!

    + + diff --git a/webapp/web/i18n/files/passwordResetPending.txt b/webapp/web/i18n/files/passwordResetPending.txt new file mode 100644 index 000000000..5d34952f3 --- /dev/null +++ b/webapp/web/i18n/files/passwordResetPending.txt @@ -0,0 +1,16 @@ +Dear {2} {3}: + +We have received a request to reset the password for your {0} account +({4}). + +Please follow the instructions below to proceed with your password reset. + +If you did not request this new account you can safely ignore this email. +This request will expire if not acted upon within 30 days. + +Paste the link below into your browser's address bar to reset your password +using our secure server. + +{5} + +Thank you! \ No newline at end of file diff --git a/webapp/web/js/account/accountUtils.js b/webapp/web/js/account/accountUtils.js index 134009f61..26b0f75aa 100644 --- a/webapp/web/js/account/accountUtils.js +++ b/webapp/web/js/account/accountUtils.js @@ -45,7 +45,7 @@ $(document).ready(function(){ if (countAccount == 0){ return false; }else{ - var answer = confirm( 'Are you sure you want to delete ' + ((countAccount > 1) ? 'these accounts' : 'this account') +'?'); + var answer = confirm( ((countAccount > 1) ? confirm_delete_account_plural : confirm_delete_account_singular) +'?'); return answer; } }); diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl index 35bb89956..a855f13c8 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl @@ -2,67 +2,22 @@ <#-- Confirmation that an account has been created. --> -<#assign subject = "Your ${siteName} account has been created." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

    - ${userAccount.firstName} ${userAccount.lastName} -

    - -

    - Congratulations! -

    - -

    - We have created your new account on ${siteName}, associated with ${userAccount.emailAddress}. -

    - -

    - If you did not request this new account you can safely ignore this email. - This request will expire if not acted upon for 30 days. -

    - -

    - Click the link below to create your password for your new account using our secure server. -

    - -

    - ${passwordLink} -

    - -

    - If the link above doesn't work, you can copy and paste the link directly into your browser's address bar. -

    - -

    - Thanks! -

    - - - +<#assign subject = strings.account_created(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.account_created_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> -Congratulations! - -We have created your new account on ${siteName}, -associated with ${userAccount.emailAddress}. - -If you did not request this new account you can safely ignore this email. -This request will expire if not acted upon for 30 days. - -Paste the link below into your browser's address bar to create your password -for your new account using our secure server. - -${passwordLink} - -Thanks! - +<#assign text = strings.account_created_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl index df2959656..a6bc6f0e9 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl @@ -2,42 +2,18 @@ <#-- Confirmation that an account has been created. --> -<#assign subject = "Your ${siteName} account has been created." /> +<#assign subject = strings.account_created(siteName) /> -<#assign html> - - - ${subject} - - -

    - ${userAccount.firstName} ${userAccount.lastName} -

    - -

    - Congratulations! -

    - -

    - We have created your new VIVO account associated with ${userAccount.emailAddress}. -

    - -

    - Thanks! -

    - - - +<#assign html = strings.account_created_external_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} - -Congratulations! - -We have created your new VIVO account associated with -${userAccount.emailAddress}. - -Thanks! - +<#assign text = string.account_created_external_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl index 26f1eee4a..9ec2e5a22 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl @@ -2,71 +2,54 @@ <#-- Template for adding a user account --> -

    > Add new account

    +<#assign strings = i18n() /> +

    > ${strings.add_new_account}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorExternalAuthIdInUse??> + <#assign errorMessage = strings.error_external_auth_already_exists /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> + <#elseif errorNoRoleSelected??> + <#assign errorMessage = strings.error_no_role /> + <#elseif errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> + <#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> + <#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorExternalAuthIdInUse??> - <#assign errorMessage = "An account with that external authorization ID already exists." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - - <#if errorNoRoleSelected??> - <#assign errorMessage = "You must select a role." /> - - - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> - - + <#if errorMessage?has_content>
    - + - + - + <#include "userAccounts-associateProfilePanel.ftl"> -

    checked />Externally Authenticated Only

    -

    Roles *

    +

    checked />${strings.external_auth_only}

    +

    ${strings.roles} *

    <#list roles as role> @@ -74,25 +57,21 @@ <#if emailIsEnabled??> -

    - Note: An email will be sent to the address entered above - notifying that an account has been created. - It will include instructions for activating the account and creating a password. -

    +

    ${strings.new_account_note}

    <#else>
    - + -

    Minimum of ${minimumLength} characters in length.

    +

    ${strings.minimum_password_length}

    - +
    -

    or Cancel

    +

    ${strings.or} ${strings.cancel_link}

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl index f75ef2856..3cf0bedff 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl @@ -2,20 +2,22 @@ <#-- Template for setting the account reference field, which can also associate a profile with the user account --> +<#assign strings = i18n() /> + ${stylesheets.add('', '')}
    <#if showAssociation??> - + - This Identifier is already in use. -

    Can be used to associate the account with the user's profile via the matching property.

    + ${strings.auth_id_in_use} +

    ${strings.auth_id_explanation}

    <#else> - + - This Identifier is already in use. + ${strings.auth_id_in_use}
    @@ -24,10 +26,10 @@ ${stylesheets.add('

    - + - (verify this match) - (change profile) + (${strings.verify_this_match}) + (${strings.change_profile})

    @@ -37,16 +39,16 @@ ${stylesheets.add('

    - +

    -

    - or -

    +

    - ${strings.or} -

    - + - + -

    Minimum of ${minimumLength} characters in length.

    +

    ${strings.minimum_password_length(minimumLength)}

    - + -

    +

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl index e5b348fdc..a871b8090 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl @@ -2,75 +2,58 @@ <#-- Template for editing a user account --> -

    > Edit account

    +<#assign strings = i18n() /> +

    > ${strings.edit_account}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> - - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorExternalAuthIdInUse??> - <#assign errorMessage = "An account with that external authorization ID already exists." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - - <#if errorNoRoleSelected??> - <#assign errorMessage = "You must select a role." /> - - - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorExternalAuthIdInUse??> + <#assign errorMessage = strings.error_external_auth_already_exists /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> + <#elseif errorNoRoleSelected??> + <#assign errorMessage = strings.error_no_role /> + <#elseif errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> + <#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> + <#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> <#if errorMessage?has_content>
    - + - + - + <#if externalAuthPermitted??> <#include "userAccounts-associateProfilePanel.ftl"> -

    checked />Externally Authenticated Only

    +

    checked />${strings.external_auth_only}

    <#if roles?has_content> -

    Roles *

    +

    ${strings.roles} *

    <#list roles as role> @@ -81,29 +64,25 @@ <#if emailIsEnabled??>
    class="hidden" role="region"> checked /> - + -

    - Note: Instructions for resetting the password will - be emailed to the address entered above. The password will not - be reset until the user follows the link provided in this email. -

    +

    ${strings.reset_password_note}

    <#else>
    class="hidden" role="region"> - + -

    Minimum of ${minimumLength} characters in length.
    - Leaving this blank means that the password will not be changed.

    +

    ${strings.minimum_password_length(minimumLength)}
    + ${strings.leave_password_unchanged}

    - +
    -

    or Cancel

    +

    ${strings.or} ${strings.cancel_link}

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl index a1f725bca..96bdb70eb 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl @@ -2,59 +2,55 @@ <#-- Template for creating an account for the first time an external user logs in. --> -

    First time log in

    +<#assign strings = i18n() /> + +

    ${strings.first_time_login}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - + <#if errorMessage?has_content>
    -

    Please provide your contact information to finish creating your account.

    +

    ${strings.please_provide_contact_information}

    - + - + - + <#if emailIsEnabled??> -

    - Note: An email will be sent to the address entered above notifying - that an account has been created. -

    +

    ${strings.first_time_login_note}

    -

    or Cancel

    +

    + ${strings.or} + ${strings.cancel_link} +

    + +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl index a7b6cae83..247cc42b4 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl @@ -2,42 +2,20 @@ <#-- Confirmation that an account has been created for an externally-authenticated user. --> -<#assign subject = "Your ${siteName} account has been created." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

    - ${userAccount.firstName} ${userAccount.lastName} -

    - -

    - Congratulations! -

    - -

    - We have created your new VIVO account associated with ${userAccount.emailAddress}. -

    - -

    - Thanks! -

    - - - +<#assign subject = strings.account_created(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.first_time_external_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -Congratulations! - -We have created your new VIVO account associated with -${userAccount.emailAddress}. - -Thanks! - +<#assign text = strings.first_time_external_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl index 70b9c3e60..d9c5aa06c 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl @@ -4,20 +4,19 @@ <#import "userAccounts-accountsNav.ftl" as p> +<#assign strings = i18n() /> +
    -

    User accounts |

    +

    ${strings.user_accounts_link} |

    <#if newUserAccount?? > @@ -25,14 +24,10 @@ <#if updatedUserAccount?? > @@ -40,7 +35,7 @@ <#if deletedAccountCount?? > @@ -48,7 +43,7 @@
    <#if roleFilterUri?has_content> - View all accounts + ${strings.view_all_accounts}
    @@ -68,7 +63,7 @@
    - + <#else> @@ -156,7 +151,7 @@ <#if account.editUrl != ""> - ${account.emailAddress} + ${account.emailAddress} <#else> ${account.emailAddress} @@ -185,5 +180,10 @@ <@p.accountsNav />
    + + ${stylesheets.add('')} ${scripts.add('')} \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl index 27add004a..8f8c8bd00 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl @@ -2,58 +2,48 @@ <#-- Template for editing a user account --> -

    My account

    +<#assign strings = i18n() /> + +

    ${strings.myAccount_heading}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> + <#elseif errorNoRoleSelected??> + <#assign errorMessage = strings.error_no_role /> + <#elseif errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> + <#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> + <#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> - - + <#if errorMessage?has_content> <#if confirmChange??> - <#assign confirmMessage = "Your changes have been saved." /> + <#assign confirmMessage = strings.myAccount_confirm_changes /> <#if confirmEmailSent??> - <#assign confirmMessage = "Your changes have been saved. A confirmation email has been sent to ${emailAddress}." /> + <#assign confirmMessage = strings.myAccount_confirm_changes_plus_note(emailAddress) /> <#if confirmMessage?has_content> @@ -63,30 +53,34 @@ <#include "userAccounts-myProxiesPanel.ftl"> - + -

    Note: if email changes, a confirmation email will
    be sent to the new email address entered above.

    +

    ${strings.email_change_will_be_confirmed}

    - + - + <#if !externalAuth??> - + -

    Minimum of ${minimumLength} characters in length.
    If left blank, the password will not be changed.

    +

    ${strings.minimum_password_length(minimumLength)}
    ${strings.leave_password_unchanged}

    - + -

    or Cancel

    +

    + + ${strings.or} + ${strings.cancel_link} +

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl index 8c27c659f..02edecc87 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl @@ -2,15 +2,21 @@ <#-- Template for setting the account reference field, which can also associate a profile with the user account --> +<#assign strings = i18n() /> +
    -

    Who can edit my profile

    +

    ${strings.who_can_edit_profile}

    - - + + + -

     

    +

    +   +

    ${myAccountUri}

    -

    Selected editors:

    +

    ${strings.selected_editors}:

    <#-- Magic ul that holds all of the proxy data and the template that shows how to display it. -->
      @@ -35,7 +41,7 @@

      %label% | %classLabel%
      - Remove selection + ${strings.remove_selection}

      diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl index 4177027ab..1a4941549 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl @@ -2,42 +2,20 @@ <#-- Confirmation that an password has been created. --> -<#assign subject = "Your ${siteName} password has successfully been created." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

      - ${userAccount.firstName} ${userAccount.lastName} -

      - -

      - Password successfully created. -

      - -

      - Your new password associated with ${userAccount.emailAddress} has been created. -

      - -

      - Thank you. -

      - - - +<#assign subject = strings.password_created_subject(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.password_created_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -Password successfully created. - -Your new password associated with ${userAccount.emailAddress} -has been created. - -Thank you. - +<#assign text = strings.password_created_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl index 8fd529c79..8badf9f3b 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl @@ -2,42 +2,20 @@ <#-- Confirmation that a password has been reset. --> -<#assign subject = "Your ${siteName} password changed." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

      - ${userAccount.firstName} ${userAccount.lastName} -

      - -

      - Password successfully changed. -

      - -

      - Your new password associated with ${userAccount.emailAddress} has been changed. -

      - -

      - Thank you. -

      - - - +<#assign subject = strings.password_reset_complete_subject(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.password_reset_complete_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -Password successfully changed. - -Your new password associated with ${userAccount.emailAddress} -has been changed. - -Thank you. - +<#assign text = strings.password_reset_complete_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl index d6fcc59a2..e02bdfd9a 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl @@ -2,60 +2,22 @@ <#-- Confirmation email for user account password reset --> -<#assign subject = "${siteName} reset password request" /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

      - Dear ${userAccount.firstName} ${userAccount.lastName}: -

      - -

      - We have received a request to reset the password for your ${siteName} account (${userAccount.emailAddress}). -

      - -

      - Please follow the instructions below to proceed with your password reset. -

      - -

      - If you did not request this new account you can safely ignore this email. - This request will expire if not acted upon within 30 days. -

      - -

      - Click on the link below or paste it into your browser's address bar to reset your password - using our secure server. -

      - -

      ${passwordLink}

      - -

      Thank you!

      - - - +<#assign subject = strings.password_reset_pending_subject(siteName) /> -<#assign text> -Dear ${userAccount.firstName} ${userAccount.lastName}: - -We have received a request to reset the password for your ${siteName} account -(${userAccount.emailAddress}). +<#assign html = strings.password_reset_pending_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> -Please follow the instructions below to proceed with your password reset. - -If you did not request this new account you can safely ignore this email. -This request will expire if not acted upon within 30 days. - -Paste the link below into your browser's address bar to reset your password -using our secure server. - -${passwordLink} - -Thank you! - +<#assign text = strings.password_reset_pending_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl index d7630d5fb..0ca4be7b6 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl @@ -2,45 +2,43 @@ <#-- Template for adding a user account --> -

      Reset your Password

      +<#assign strings = i18n() /> -

      Please enter your new password for ${userAccount.emailAddress}

      +

      ${strings.reset_your_password}

      - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> - - - <#if errorMessage?has_content> - - +

      ${strings.enter_new_password(userAccount.emailAddress)}

      + +<#if errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> +<#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> +<#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> + + +<#if errorMessage?has_content> + +
      - + -

      Minimum of ${minimumLength} characters in length.

      +

      ${strings.minimum_password_length(minimumLength)}

      - + -

      +

      -

      * required fields

      +

      * ${strings.required_fields}

      From 1ca09049118bceaae22b228027220c4fa5782100 Mon Sep 17 00:00:00 2001 From: tworrall Date: Tue, 30 Apr 2013 14:47:31 -0400 Subject: [PATCH 06/18] changes for the home page redesign --- .../freemarker/HomePageController.java | 9 ++ .../freemarker/IndividualListController.java | 13 ++- .../individual/IndividualResponseBuilder.java | 2 +- .../GetRandomSolrIndividualsByVClass.java | 84 +++++++++++++++++++ .../json/GetSolrIndividualsByVClass.java | 8 +- .../webapp/controller/json/JsonServlet.java | 31 +++++++ .../controller/PagedSearchController.java | 3 +- .../webapp/utils/solr/SolrQueryUtils.java | 32 +++++++ webapp/themes/vitro/templates/page-home.ftl | 24 ++---- webapp/web/css/vitro.css | 8 +- webapp/web/js/vitroUtils.js | 29 +------ .../templates/freemarker/body/login/login.ftl | 5 +- .../freemarker/lib/lib-home-page.ftl | 73 ++++++++++++++++ 13 files changed, 270 insertions(+), 51 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java mode change 100755 => 100644 webapp/web/js/vitroUtils.js create mode 100644 webapp/web/templates/freemarker/lib/lib-home-page.ftl diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java index 6dfa102d7..22aaaa804 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java @@ -9,6 +9,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; @@ -48,6 +49,7 @@ public class HomePageController extends FreemarkerHttpServlet { } }*/ body.put("dataServiceUrlVClassesForVClassGroup", UrlBuilder.getUrl("/dataservice?getVClassesForVClassGroup=1&classgroupUri=")); + body.put("geoFocusMapsEnabled", getGeoFocusMapsFlag(vreq)); return new TemplateResponseValues(BODY_TEMPLATE, body); } @@ -61,4 +63,11 @@ public class HomePageController extends FreemarkerHttpServlet { protected String getPageTemplateName() { return PAGE_TEMPLATE; } + + private boolean getGeoFocusMapsFlag(VitroRequest vreq) { + String property = ConfigurationProperties.getBean(vreq).getProperty( + "homePage.geoFocusMaps"); + return "enabled".equals(property); + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java index 77f1cc601..54b295e6d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java @@ -182,8 +182,19 @@ public class IndividualListController extends FreemarkerHttpServlet { } return rvMap; } - + public static Map getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao, ServletContext context) { + Map rvMap = new HashMap(); + try{ + List classUris = Collections.singletonList(vclassURI); + IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteRandomVClassQuery(classUris, page, pageSize, context, indDao); + rvMap = getResultsForVClassQuery(results, page, pageSize, ""); + } catch(Throwable th) { + log.error("An error occurred retrieving random results for vclass query", th); + } + return rvMap; + } + //TODO: Get rid of this method and utilize SolrQueryUtils - currently appears to be referenced //only within DataGetterUtils public static long getIndividualCount(List vclassUris, IndividualDao indDao, ServletContext context) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java index ac39c3b10..e63791df5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java @@ -180,7 +180,7 @@ class IndividualResponseBuilder { private boolean getprofilePageTypesFlag() { String property = ConfigurationProperties.getBean(vreq).getProperty( - "MultiViews.profilePageTypes"); + "multiViews.profilePageTypes"); return "enabled".equals(property); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java new file mode 100644 index 000000000..5e4c268dd --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java @@ -0,0 +1,84 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.json; + +import java.util.Arrays; +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 org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewService; +import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewService.ShortViewContext; +import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewServiceSetup; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel; + +/** + * Does a Solr search for individuals, and uses the short view to render each of + * the results. + */ +public class GetRandomSolrIndividualsByVClass extends GetSolrIndividualsByVClass { + private static final Log log = LogFactory + .getLog(GetRandomSolrIndividualsByVClass.class); + + protected GetRandomSolrIndividualsByVClass(VitroRequest vreq) { + super(vreq); + } + + /** + * Search for individuals by VClass. + */ + @Override + protected JSONObject process() throws Exception { + JSONObject rObj = null; + + //This gets the first vclass value and sets that as display type. + List vclassIds = super.getVclassIds(vreq); + String vclassId = vclassIds.get(0); + vreq.setAttribute("queryType", "random"); +// vreq.setAttribute("displayType", vclassId); + + //This will get all the solr individuals by VClass (if one value) or the intersection + //i.e. individuals that have all the types for the different vclasses entered + rObj = super.process(); + addShortViewRenderings(rObj); + return rObj; + } + + /** + * Look through the return object. For each individual, render the short + * view and insert the resulting HTML into the object. + */ + private void addShortViewRenderings(JSONObject rObj) throws JSONException { + JSONArray individuals = rObj.getJSONArray("individuals"); + String vclassName = rObj.getJSONObject("vclass").getString("name"); + for (int i = 0; i < individuals.length(); i++) { + JSONObject individual = individuals.getJSONObject(i); + individual.put("shortViewHtml", + renderShortView(individual.getString("URI"), vclassName)); + } + } + + private String renderShortView(String individualUri, String vclassName) { + IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao(); + Individual individual = iDao.getIndividualByURI(individualUri); + + Map modelMap = new HashMap(); + modelMap.put("individual", + new IndividualTemplateModel(individual, vreq)); + modelMap.put("vclass", vclassName); + + ShortViewService svs = ShortViewServiceSetup.getService(ctx); + return svs.renderShortView(individual, ShortViewContext.BROWSE, + modelMap, vreq); + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java index 154753322..0d40e6026 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java @@ -24,6 +24,7 @@ public class GetSolrIndividualsByVClass extends JsonObjectProducer { protected JSONObject process() throws Exception { VClass vclass=null; + String queryType = (String) vreq.getAttribute("queryType"); String vitroClassIdStr = vreq.getParameter("vclassId"); if ( vitroClassIdStr != null && !vitroClassIdStr.isEmpty()){ vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr); @@ -35,8 +36,13 @@ public class GetSolrIndividualsByVClass extends JsonObjectProducer { log.debug("parameter vclassId URI parameter expected "); throw new Exception("parameter vclassId URI parameter expected "); } + vreq.setAttribute("displayType", vitroClassIdStr); - return JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), vreq, ctx); + if ( queryType != null && queryType.equals("random")){ + return JsonServlet.getRandomSolrIndividualsByVClass(vclass.getURI(), vreq, ctx); + } else { + return JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), vreq, ctx); + } } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java index be3c2eb01..2fbd9d09f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java @@ -72,7 +72,10 @@ public class JsonServlet extends VitroHttpServlet { new GetDataForPage(vreq).process(resp); }else if( vreq.getParameter("getRenderedSolrIndividualsByVClass") != null ){ new GetRenderedSolrIndividualsByVClass(vreq).process(resp); + }else if( vreq.getParameter("getRandomSolrIndividualsByVClass") != null ){ + new GetRandomSolrIndividualsByVClass(vreq).process(resp); } + } @@ -135,7 +138,35 @@ public class JsonServlet extends VitroHttpServlet { return value; } + public static JSONObject getRandomSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception { + VitroRequest vreq = new VitroRequest(req); + + Map map = getRandomSolrVClassResults(vclassURI, vreq, context); + //last parameter indicates single vclass instead of multiple vclasses + return processVClassResults(map, vreq, context, false); + } + //Including version for Random Solr query for Vclass Intersections + private static Map getRandomSolrVClassResults(String vclassURI, VitroRequest vreq, ServletContext context){ + log.debug("Retrieving random Solr intersection results for " + vclassURI); + + int page = IndividualListController.getPageParameter(vreq); + int pageSize = Integer.parseInt(vreq.getParameter("pageSize")); + log.debug("page and pageSize parameters = " + page + " and " + pageSize); + Map map = null; + try { + map = IndividualListController.getRandomResultsForVClass( + vclassURI, + page, + pageSize, + vreq.getWebappDaoFactory().getIndividualDao(), + context); + } catch(Exception ex) { + log.error("Error in retrieval of search results for VClass " + vclassURI, ex); + } + + return map; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java index d85ba6ada..7889a825a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java @@ -211,7 +211,8 @@ public class PagedSearchController extends FreemarkerHttpServlet { Map body = new HashMap(); - String classGroupParam = vreq.getParameter(PARAM_CLASSGROUP); + String classGroupParam = vreq.getParameter(PARAM_CLASSGROUP); + log.debug("Query text is \""+ classGroupParam + "\""); boolean classGroupFilterRequested = false; if (!StringUtils.isEmpty(classGroupParam)) { VClassGroup grp = grpDao.getGroupByURI(classGroupParam); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java index c90281377..608ae0efc 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java @@ -190,6 +190,26 @@ public class SolrQueryUtils { } } + public static SolrQuery getRandomQuery(List vclassUris, int page, int pageSize){ + String queryText = ""; + + try { + queryText = makeMultiClassQuery(vclassUris); + log.debug("queryText is " + queryText); + SolrQuery query = new SolrQuery(queryText); + + //page count starts at 1, row count starts at 0 + query.setStart( page ).setRows( pageSize ); + + log.debug("Query is " + query.toString()); + return query; + + } catch (Exception ex){ + log.error("Could not make the Solr query",ex); + return new SolrQuery(); + } + } + public static String makeMultiClassQuery( List vclassUris){ List queryTypes = new ArrayList(); try { @@ -217,4 +237,16 @@ public class SolrQueryUtils { return results; } + public static IndividualListQueryResults buildAndExecuteRandomVClassQuery( + List vclassURIs, int page, int pageSize, + ServletContext context, IndividualDao indDao) + throws SolrServerException { + SolrQuery query = SolrQueryUtils.getRandomQuery(vclassURIs, page, pageSize); + IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao, context); + log.debug("Executed solr query for " + vclassURIs); + if (results.getIndividuals().isEmpty()) { + log.debug("entities list is null for vclass " + vclassURIs); + } + return results; + } } diff --git a/webapp/themes/vitro/templates/page-home.ftl b/webapp/themes/vitro/templates/page-home.ftl index a052acfe2..c4816bc95 100644 --- a/webapp/themes/vitro/templates/page-home.ftl +++ b/webapp/themes/vitro/templates/page-home.ftl @@ -1,7 +1,7 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> <@widget name="login" include="assets" /> -<#include "browse-classgroups.ftl"> +<#import "lib-home-page.ftl" as lh> @@ -36,17 +36,14 @@
      +
      filter search @@ -57,19 +54,12 @@ <@widget name="login" /> - - <#--<@allClassGroups vClassGroups! />--> - -
      -

      Stats

      + +
      +

      Statistics

      diff --git a/webapp/web/css/vitro.css b/webapp/web/css/vitro.css index ea8b9cac4..6a84a8d24 100644 --- a/webapp/web/css/vitro.css +++ b/webapp/web/css/vitro.css @@ -341,11 +341,10 @@ a.filter-search { margin-top: 1em; width: 921px; height: 213px; - float: left; + clear: both; } -#home-stats h4 { +.home-sections h4 { margin-top: 0; - width: 64px; height: 34px; font-size: 18px; text-align: center; @@ -353,6 +352,9 @@ a.filter-search { padding: 0; line-height: 35px; } +#home-stats h4 { + width: 102px; +} #stats { margin: 0 auto; width: 875px; diff --git a/webapp/web/js/vitroUtils.js b/webapp/web/js/vitroUtils.js old mode 100755 new mode 100644 index e9b345abb..76b84d8c5 --- a/webapp/web/js/vitroUtils.js +++ b/webapp/web/js/vitroUtils.js @@ -10,15 +10,10 @@ $(document).ready(function(){ // fade in flash-message when user logs out jQuery('section#flash-message').css('display', 'none').fadeIn(1500); - ///////////////////////////// // Home search fiter // Toggle filter select list - var $searchFilterList = $('#filter-search-nav'); - var $selectedFilter; - var $queryToSend; - var $queryToSendAll = true; var $isFilterOpen = false; console.log("Filter is open = " + $isFilterOpen); @@ -63,15 +58,14 @@ $(document).ready(function(){ ev.preventDefault(); if ($(this).text() == 'All') { - $queryToSendAll = true; //Selected filter feedback $('.search-filter-selected').text(''); + $('input[name="classgroup"]').val(''); console.log("ALL"); } else { - //Selected filter feedback $('.search-filter-selected').text($(this).text()).fadeIn('slow'); - $queryToSendAll = false; + $('input[name="classgroup"]').val($(this).children("a").attr("title")); } //Hide filter select list @@ -82,10 +76,7 @@ $(document).ready(function(){ $('a.filter-search').removeClass('filter-active'); $('a.filter-search').addClass('filter-default'); - - $selectedFilter = $(this).text(); $isFilterOpen = false; - console.log("$queryToSend " + $selectedFilter); }); }); @@ -118,18 +109,4 @@ $(document).ready(function(){ console.log("HIDE input value ") ; }); - - $('#search-homepage').submit(function(){ - - if ($queryToSendAll) { - $filterType = ''; - }else { - $filterType = '&classgroup=http://vivoweb.org/ontology/vitroClassGroup' + $selectedFilter; - } - - $queryToSend = 'querytext=' + $('input.search-homepage').val() + $filterType; - console.log("Query to send: " + $queryToSend); - - return false; - }); -}); \ No newline at end of file +}); diff --git a/webapp/web/templates/freemarker/body/login/login.ftl b/webapp/web/templates/freemarker/body/login/login.ftl index e310b341e..930f195ea 100644 --- a/webapp/web/templates/freemarker/body/login/login.ftl +++ b/webapp/web/templates/freemarker/body/login/login.ftl @@ -2,4 +2,7 @@ <#-- Main template for the login page --> -<@widget name="login" /> \ No newline at end of file +<@widget name="login" /> + \ No newline at end of file diff --git a/webapp/web/templates/freemarker/lib/lib-home-page.ftl b/webapp/web/templates/freemarker/lib/lib-home-page.ftl new file mode 100644 index 000000000..7b0cac823 --- /dev/null +++ b/webapp/web/templates/freemarker/lib/lib-home-page.ftl @@ -0,0 +1,73 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Macros used to build the statistical information on the home page --> + +<#-- Get the classgroups so they can be used to qualify searches --> +<#macro allClassGroupNames classGroups> + <#list classGroups as group> + <#-- Only display populated class groups --> + <#if (group.individualCount > 0)> +
    • ${group.displayName?capitalize}
    • + + + + +<#-- builds the "stats" section of the home page, i.e., class group counts --> +<#macro allClassGroups classGroups> + <#-- Loop through classGroups first so we can account for situations when all class groups are empty --> + <#assign selected = 'class="selected" ' /> + <#assign classGroupList> + <#list classGroups as group> + <#-- Only display populated class groups --> + <#if (group.individualCount > 0)> + <#-- Catch the first populated class group. Will be used later as the default selected class group --> + <#if !firstPopulatedClassGroup??> + <#assign firstPopulatedClassGroup = group /> + + <#-- Determine the active (selected) group --> + <#assign activeGroup = "" /> + <#if !classGroup??> + <#if group_index == 0> + <#assign activeGroup = selected /> + + <#elseif classGroup.uri == group.uri> + <#assign activeGroup = selected /> + + <#if group.displayName != "equipment" && group.displayName != "locations" && group.displayName != "courses" > +
    • + +

      + <#if (group.individualCount > 10000) > + <#assign overTen = group.individualCount/1000> + ${overTen?round}k + <#elseif (group.individualCount > 1000)> + <#assign underTen = group.individualCount/1000> + ${underTen?string("0.#")}k + <#else> + ${group.individualCount}  + +

      +

      ${group.displayName?capitalize}

      +
      +
    • + + + + + + <#-- Display the class group browse only if we have at least one populated class group --> + <#if firstPopulatedClassGroup??> + ${classGroupList} + <#else> +

      There is currently no content in the system, or you need to create class groups and assign your classes to them.

      + + <#if user.loggedIn> + <#if user.hasSiteAdminAccess> +

      You can add content and manage this site from the Site Administration page.

      + + <#else> +

      Please log in to manage content.

      + + + + From afbf429165e0275bbfb98792c23be40d83652220 Mon Sep 17 00:00:00 2001 From: tworrall Date: Thu, 2 May 2013 12:31:54 -0400 Subject: [PATCH 07/18] additional home page redesign changes --- webapp/themes/vitro/images/filteredSearch.gif | Bin 0 -> 1404 bytes .../vitro/images/filteredSearchActive.gif | Bin 0 -> 1392 bytes webapp/themes/vitro/images/limit-search.png | Bin 0 -> 1707 bytes .../vitro/images/search-field-and-button.gif | Bin 0 -> 1729 bytes webapp/themes/vitro/templates/page-home.ftl | 17 ++-- webapp/web/css/vitro.css | 1 + .../freemarker/lib/lib-home-page.ftl | 74 +++++++++--------- 7 files changed, 49 insertions(+), 43 deletions(-) create mode 100644 webapp/themes/vitro/images/filteredSearch.gif create mode 100644 webapp/themes/vitro/images/filteredSearchActive.gif create mode 100644 webapp/themes/vitro/images/limit-search.png create mode 100644 webapp/themes/vitro/images/search-field-and-button.gif diff --git a/webapp/themes/vitro/images/filteredSearch.gif b/webapp/themes/vitro/images/filteredSearch.gif new file mode 100644 index 0000000000000000000000000000000000000000..16bb82be28e4b822efe9ed17ef5d9bf7f404758e GIT binary patch literal 1404 zcmZ?wbhEHbRA z9XqDap8fCNzu4sD=PzEgb$7pc`?j#GtgyU%+N@cvU0p|x9eefqwVs(-VtV?FIddjW zo0eN#+%sXq!6QeSJ38##+>V_%5uKP=-`xEF|9@RmQwFL6#sAz9z5xm@i6x0Z+Qz=3 zATc>RwL~E)H9a%WR_Xoj{Yna%DYi=CroINg16w1-Ypui3%0DIeEoa6}C!=DfvmMRzNmLSYJs2tfVB{R>=`0p#ZYeIlm}X!Bo#! zH`&0@P{GVh&(Orw%*;?n!N|bSNZ$a6%ybP+tW3?UjLa3FKnZADQA(Oskc%7CE+EfV zDWjyMz)D}gyu4hm+*mKaC|%#s($W%ShLMpjP=#)BWnM{Qg>GK4GRy>*)Z*l#%z~24 z{5%DaiHS-1r6smXK$k+ikXryZHm_I@>>a)2{9OHt!~%UoJp+)JUEg{v+u z2}(t{7puX=A(aKG`a!A1`K3k4sX*n*AgcnUy@&(kzb(T z9Bihb;hUJ8nFkWk1ncniwerj>E=kNwPW5!LRRWr!mzkMjWntuOYG7h+Y3l6eY-s3e zWMSmyYylK9b}@3cFgLJ(>2=9ZF3nBND}m`vLFjeFsTY(OatnYqyQCInmZhe+73JqD zfIV%MiQ6saIL(9VO~LIJ3!HlOfsWA!MJ-ZP!-Rn82gHOYTp$OY^i%VI>AeV;uo?gV z`}^njub)4@fBX97^QVs=-oJbM=Jl(WFP=Yp`sDGWhY#-GyL;#Mt(!NlU%Ptc@}-Lx z&YwGb=JctPCypOGdgSn-g9rBS+q-A?uAMu!Z`-%OrteG>WPn$Yr@}!9q`ulo&y1P0%+S^)NnwuIM>g#H2s;eq1%F9Yiii-*h z^7C?Yva>QX($i8?l9Lh>;^SgtqN5@s!oxyCf`bAB{QZ1=yuCa<+}&JVoShsU?CorA ztgS39%*{+qjExKp^!0Rgw6!!f)YVi~l$8_}{xws^R!vBYMYv7 z%$ZYIR(9;fiRUj~OrJe_(zI#K9Ua?t?8q%H?wK&b&dn`0Ir-JASBdHA|Ni}J?do#$ z@Q6-KJb2_tVR`wRw{Ks)e%;pH{r~@eT~kvA8UV%r+!4M33NDEyi9p)MzM>#8IXksP zAt^OIGtXA({qFrr3YjUkO5vuy2EGN(sTr9bRYj@6RemAKRoTgwDN6Qs3N{s16}bhu zsU?XD6}dTi#a0!zN{K1?NvT#qHb_`sNdc^+B->WW5hS4iveP-gC{@8!&saCvz|c^^ z%uLVF#MI2pP)EVYz|ctF0Eof6`()~Xj@TAnpKdC8`Lf!&sHg;q@=(~ zU%$M(T(8_%FTW^V-_X+15@d#vkuFe$ZgFK^Nn(X=Ua>OF1ees}+TSP$$Sz2y8{{ffi_eM3D1ke6TzeSPsO&CP|YE-nd5MYtEM z!Nnn!1*!T$sm1xFMaii^<;ozd3ap%qQWHz^i$e1Ab6}wukda@KU!0L&px_*Arl8@Q zn4Fmh63_(e@b$Iw%quQQ%u7!7bg@+enxU7OnPTN;;^t&xX=Y^VVqjuu=xStPyn>bnwy$e0@Is<&})oSFDNnO765H_NiE7OOHFYr%Fk5*d)g`! zi(4#=fEJsWyO}z>Ib(MVL~jZfw?On-7~s^a4|I$^C~A?S8YToxKOiPN;Q~4Eq@S7x zOz%a&gw6Q>-`_vKfBpRN{oB_spFe&4@c!M~H?Lp4eDVC*(TITuzuazHLF*x zT(NxF(j|)*EnF~v-rPB}XU&{3ecIG1lP67_(BIeF)7{nC(caeD(%jV8P+wPDQ(aYA zQC?PBQe0G6ke`>Elbw~Bk)D>ClAM&75FZyC6CD*95gryA5*!p5;P2<_Vr*n+ps%N^qphW>p{}N?qO7E-ATK8?BP}HQR1~W zYW0Gf)>Lewrw6J71g}cciy|Z^~Bd=W{zlKg(@Z?`F5!& yfd+nMIhHEfXhlgSPG_FUyrMB8+^$^g(y7Z=tX#Ev&DwSAH*DOrc}svJgEauW4exmX literal 0 HcmV?d00001 diff --git a/webapp/themes/vitro/images/limit-search.png b/webapp/themes/vitro/images/limit-search.png new file mode 100644 index 0000000000000000000000000000000000000000..9eabf8cd02eb12d93f67bbf14975a72207ee287f GIT binary patch literal 1707 zcmbVNdr;GM91k!RaWGbxCy0^-5p~igebLlbrL;WMB3G)k^Rb3Dln8A~8l)gTfQf)Z zPzD^L;MA#{6G6mNdCB3X9uDRWpWwtHI6WU6ZX&yJE=6$Lo#!9RCHeh+-+Vux@B5M) z6&dF0;_U(efNMm!T*a&;^LRK>|76KV~uQLYf{NfR5h>#%Jm3xfs#$r76d(gSTvlM#X&;o&kK?=nP zl(5ngg2xl#X%rrv7OB>!CFoHDv}7?Tv56T16Ha5G&6H@iifvM8j91L;?P3lDj;YWI zQs|9S8f6q1LQ*&=VDkd?FoJ+WAsgWfghFH?$b}Iu2WD?!hZ80Y)6i?F@F^7|qlEO~mu}R9vK~NO6b8xwVj7Fd})l6fyK(p0vfK z!8t12N+wf!rXF#A6JREH?>A&uWV{itqzI-cSfZTNC!26H9U+%O%onzSFoTRB(g&Xefi`3SeQdLJ_2x zz($y@G-lT06Lty4?l=~HFIF5v;TTO)YLZNx=zyqrk|wS3qy-F#7J~DXn4U1(1@r9% zdK0f4r-+TXA(SFb;8=#m#5+8I1^Wb zE)ycA2kqOp&CeX(jt_2TW`<&h!?*$H0|3X{5%OTQ?amWzAlV(|nS7*XZ~3JjN&i6Y zO!}`lgvb7rcHoSlD;>XyyEolIB%sT;_Gw3LS@X8fOej zl3t&@lDd9b+0qvja&^stLq9b4uIc$E|M@XLPu<*KH#<*{b<6zp%E0l#7C~Ik&K%9I zUUa0`qnVc(w&#LJONpvg<%0GbM8#>h?q3;|1+-#+Ug(cIxDItYCmhnrU=AJELeV_;hwF5`FdZPuY+9R^(@7+?s|XRC5^0ZdtXt zsIOXGzCV%geYdd1_l5V9fH}pt%N#vDGVm;QeeDGnyghHr%J3uy*za1iTV5B`>A$Ts zaaexf){T++SF=-mj-GKvoz4=QlDIF~of`+;ht4=H-L5NkxOl7Ban!qL5uu4*-Yy=P znmvpKIM{M~Q#F-GV%ur~=W}~>-F4d18DIM99-iuKt(jAyc`$jY8>?|yO}C3z8CS3#)uCpG+g{X6eyoP$P zb^DGl&tToFaM-}!H7U8IP2W}4d{etid!*?zOH2E2dCsEQI&DfRflk|aj?=UAL_>aA zkzXnVn_{fr`Uiog{u*V&5Ok=ezH78{xN>~~YVAcA6^*iVfHLWq16!STbl86%5sFB8 IwM>`!H+Bq+%K!iX literal 0 HcmV?d00001 diff --git a/webapp/themes/vitro/images/search-field-and-button.gif b/webapp/themes/vitro/images/search-field-and-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b672288e335881ca19c6a17014e005a70905349 GIT binary patch literal 1729 zcmbVM2~-nD7!Dvx3$#>gtG3lO*cJ;UySYfBQ6UGHC*-`adj6kSwa(2 zd%{Hmp{uJaSRxT4NJ2_VPfyR#(2&7k(ChX6I^E#lVE@2CLUMAKRy!~_sMG1-HEV|S z`p(YIj*gB%k!WamnDAd?w!zZh%NyVcF(E$BU#OM~MWHYT1i`_Gj6>`#tt0}7m_uAn z_X54-TsQ=Ai&VhAkxTqUk)a}%n7D8OFkj79OXX4+69Q_fM5bh`IYglt4T9PD+9)Oy zfl&w+${{)%4*;W0E~5E_PYh`6V(Ly*e7yxu65DM_ONkwmDJtQN}25D6qprN+2M(Mrq* z{@abWqLqFTa+vG`E73582*%;I<77N{?>1xv;@+^ADiHiqgc2Sq3X{Sz%$>&};wL0A zB4&dS6VIX(4RoS_3?>AzC@!Eg*TscSg+PHblRmEFZCoaWO9yFAd^%Uag&;nKNfB_F zxQNQ5aG6dZbDZlgQ({7y2p+eK;C9EjymxZhTm>w|P=z0gO2#X|I|Rj0We6$4?ya_BWHq4Dxc*-cj40nG#-sd9OH`r zPu9q|Gh}0V{G(jPMR*Mwmv4$6-@IubScdnE0&flz!>d0>UcMOC4-M)D`um+N~k zt?laUc=Gts!w2{8wYS~9)7o)%q)SwKdhhUA}bj!ufMml@;Y> zr6t8hXA931Xin$noyt9#lb!YJiOl22GSZJ8Ih>Z7lAM&7aOmKH{rmRriQm0z=Z@`h z+hVuIY}vdiI%?yFU)HZ%`*UQ3I$RZoDHT7-QJGW{x&{deUJZ*yLBbzb1qQ7A;rkW- z%fDOZ=j-#W_tGU^i#x35ZLi^2mDtT;#;)oNMU8|VALV?sD#SatIY(9Z zG_tZiPraCw)X-57SuZPXd!}Ee&uQt^k3?}QL`=CqPUHRzAGtbVa1G>S4 z-sdj_{X?$|1jEA?*Su9#(H2u=#A@%<^D#EIs_D%(sm`&}sD-b<#>J4q1CFKSWRYw3){YL#J#{S`LK1&jDXtfRz6!ik~~ss zA0f_J{u=g~EOOS(Q~Y9;xo2Vb)cogVi2>P@Px1@pnI)V|Ms7f?l5_XYODg$n$yzhB zfl}+d_6s@-SL*hneD4K}l~$U^4K++{pH)c#xvAJKDbUf9o@-&_ zU$?$HajJ>AMj4%5?onkzSch4*U1_;SFq>rI=6|)Uxc^CGx@X#w@)Di4SrgiJwY+qw XxBWugtfdtrefM|Hw6e1?CCvK^WSi57 literal 0 HcmV?d00001 diff --git a/webapp/themes/vitro/templates/page-home.ftl b/webapp/themes/vitro/templates/page-home.ftl index c4816bc95..0e3ab91f4 100644 --- a/webapp/themes/vitro/templates/page-home.ftl +++ b/webapp/themes/vitro/templates/page-home.ftl @@ -55,14 +55,17 @@ <@widget name="login" /> -
      -

      Statistics

      - -
        - <@lh.allClassGroups vClassGroups! /> -
      -
      + + <@lh.allClassGroups vClassGroups! /> <#include "footer.ftl"> + \ No newline at end of file diff --git a/webapp/web/css/vitro.css b/webapp/web/css/vitro.css index 6a84a8d24..54e42a6c3 100644 --- a/webapp/web/css/vitro.css +++ b/webapp/web/css/vitro.css @@ -251,6 +251,7 @@ p#mngLabelsText { /* SEARCH HOME------> */ #search-home { margin-top: 2em; + width: 570px; } #search-home h3 { diff --git a/webapp/web/templates/freemarker/lib/lib-home-page.ftl b/webapp/web/templates/freemarker/lib/lib-home-page.ftl index 7b0cac823..e184a1cac 100644 --- a/webapp/web/templates/freemarker/lib/lib-home-page.ftl +++ b/webapp/web/templates/freemarker/lib/lib-home-page.ftl @@ -17,49 +17,51 @@ <#-- Loop through classGroups first so we can account for situations when all class groups are empty --> <#assign selected = 'class="selected" ' /> <#assign classGroupList> - <#list classGroups as group> - <#-- Only display populated class groups --> - <#if (group.individualCount > 0)> - <#-- Catch the first populated class group. Will be used later as the default selected class group --> - <#if !firstPopulatedClassGroup??> - <#assign firstPopulatedClassGroup = group /> - - <#-- Determine the active (selected) group --> - <#assign activeGroup = "" /> - <#if !classGroup??> - <#if group_index == 0> - <#assign activeGroup = selected /> +
      +

      Statistics

      + +
      <#-- Display the class group browse only if we have at least one populated class group --> <#if firstPopulatedClassGroup??> ${classGroupList} <#else> -

      There is currently no content in the system, or you need to create class groups and assign your classes to them.

      +

      There is currently no content in the system, or you need to create class groups and assign your classes to them.

      <#if user.loggedIn> <#if user.hasSiteAdminAccess> From 90441e396923771ddbc8a2bc2a8c18779feb66de Mon Sep 17 00:00:00 2001 From: tworrall Date: Fri, 3 May 2013 16:23:14 -0400 Subject: [PATCH 08/18] modified index page to prevent a fourth column that displays outside the standard margins --- .../web/templates/freemarker/body/classGroups.ftl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/webapp/web/templates/freemarker/body/classGroups.ftl b/webapp/web/templates/freemarker/body/classGroups.ftl index 9d12507d7..ab5307be4 100644 --- a/webapp/web/templates/freemarker/body/classGroups.ftl +++ b/webapp/web/templates/freemarker/body/classGroups.ftl @@ -8,6 +8,9 @@
      <#list classGroups as classGroup> + <#assign groupSize = classGroup.classes?size > + <#assign classCount = 0 > + <#assign splitGroup = false> <#-- Only render classgroups that have at least one populated class --> <#if (classGroup.individualCount > 0)>
      @@ -17,6 +20,14 @@ <#-- Only render populated classes --> <#if (class.individualCount > 0)>
    • ${class.name} (${class.individualCount})
    • + <#assign classCount = classCount + 1 > + + <#if (classCount > 34) && !splitGroup > + <#assign splitGroup = true > +
    +
    +

    ${classGroup.displayName} (cont'd)

    +
    @@ -29,7 +40,7 @@ ${headScripts.add('')} -

    Menu Ordering

    +

    ${i18n().menu_ordering}

    <#-- List the menu items --> @@ -33,8 +33,8 @@
    @@ -44,7 +44,7 @@ <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >

    ${groupName?capitalize}

    <#else> -

    Properties

    +

    ${i18n().properties_capitalized}

    <#-- List the properties in the group --> diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl index e4c4a594c..f14ce8a8c 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl @@ -15,8 +15,8 @@ <#--the function replaces spaces in the name with underscores, also called for the property group menu--> <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) > <#else> - <#assign groupName = "Properties"> - <#assign groupNameHtmlId = "properties" > + <#assign groupName = "${i18n().properties_capitalized}"> + <#assign groupNameHtmlId = "${i18n().properties}" > <#if tabCount = 1 >
  • ${groupName?capitalize}
  • @@ -28,7 +28,7 @@ <#if (propertyGroups.all?size > 1) > -
  • View All
  • +
  • ${i18n().view_all}
  •  
  • @@ -38,8 +38,8 @@ <#assign verbose = (verbosePropertySwitch.currentValue)!false>
    @@ -49,7 +49,7 @@ <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) > <#else> - +
    <#-- List the properties in the group --> diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl index a7b7bf618..28603bb28 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl @@ -18,7 +18,7 @@ <#assign groupnameHtmlId = p.createPropertyGroupHtmlId(groupname) > <#-- capitalize will capitalize each word in the name; cap_first only the first. We may need a custom function to capitalize all except function words. --> -
  • ${groupname?capitalize}
  • +
  • ${groupname?capitalize}
  • diff --git a/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl b/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl index 631af8bcd..6377a922e 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl @@ -6,4 +6,4 @@ is also used to generate the property statement during a deletion. --> -${statement.label!statement.localName!} +${statement.label!statement.localName!} diff --git a/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl b/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl index 997619703..47c138c01 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl @@ -1,5 +1,4 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> <#-- Simple object property statement template --> - -${statement.name!} +${statement.name!} From c150b58c171403350ec4860b985b5fe155f87323 Mon Sep 17 00:00:00 2001 From: tworrall Date: Mon, 13 May 2013 12:21:25 -0400 Subject: [PATCH 15/18] removed values that have yet to be translated --- webapp/web/i18n/all_es.properties | 149 +----------------------------- 1 file changed, 1 insertion(+), 148 deletions(-) diff --git a/webapp/web/i18n/all_es.properties b/webapp/web/i18n/all_es.properties index 4e698c58d..6828b8a80 100644 --- a/webapp/web/i18n/all_es.properties +++ b/webapp/web/i18n/all_es.properties @@ -39,151 +39,4 @@ delete_link = Borrar foto submit_upload = Subir foto submit_save = Guardar foto -confirm_delete = ¿Seguro que quiere borrar esta foto? - -# -# "partial" individual templates ( /templates/freemarker/body/partials/individual ) -# -manage_publications = gestionar las publicaciones -manage_grants_and_projects = gestión de subvenciones y proyectos -manage_affiliated_people = gestión de personas afiliadas - -group_name = nombre de grupo -scroll_to_menus = desplazarse a los menús de grupo de propiedad -properties_capitalized = Propiedades -properties = propiedades -view_all = Ver Todos - -name = nombre - -admin_panel = Panel de Admin -edit_this_individual = Editar esta Individuo -verbose_status_on = encendido -verbose_status_off = desconectado -verbose_property_status = Display propiedad verbosa es -verbose_control = mando del verboso -verbose_turn_on = encender -verbose_turn_off = desconectar -resource_uri = URI de recurso - -individual_not_found = translate: Individual not found: -entity_to_query_for = translate: This id is the id of the entity to query for. netid also works. - = translate: -menu_ordering = translate: Menu Ordering -refresh_page_after_reordering = translate: Refresh page after reordering menu items -display_has_element_error = translate: There was an error in the system. The display:hasElement property could not be retrieved. - -return_to = translate: return to {0} - -# -# admin templates ( /templates/freemarker/body/admin ) -# -logins_already_restricted = translate: Logins are already restricted. -logins_not_already_restricted = translate: Logins are already not restricted. -logins_restricted = translate: Logins are now restricted. -logins_not_restricted = translate: Logins are no longer restricted. -remove_restrictions = translate: Remove Restrictions -restrict_logins = translate: Restrict Logins -error_alert_icon = translate: Error alert icon - -current_user = translate: Current user -ext_auth_id = translate: External Auth ID -not_logged_in = translate: Not logged in -identifiers = translate: Identifiers -associated_individuals = translate: Associated Individuals -match_by = translate: match by {0} -matching_prop_not_defined = translate: matching property is not defined -may_edit = translate: May edit -may_not_edit = translate: May not edit -none = translate: none -identifier_factories = translate: Identifier factories -policies = translate: Policies -authenticator = translate: Authenticator - -background_threads = translate: Background Threads -name_capitalized = translate: Name -work_level = translate: Work level -since = translate: Since -flags = translate: Flags - -search_index_status = translate: Search Index Status -search_index_not_connected = translate: The search index is not connected. -failed = translate: failed -check_startup_status = translate: Check startup status page and/or Tomcat logs for more information. -search_indexer_idle = translate: The search indexer is idle. -most_recent_update = translate: The most recent update was at -rebuild_button = translate: Rebuild -reset_search_index = translate: Reset the search index and re-populate it. -preparing_to_rebuild_index = translate: Preparing to rebuild the search index. -since_elapsed_time = translate: since {0}, elapsed time {1} -current_task = translate: {0} the search index -since_elapsed_time_est_total = translate: since {0}, elapsed time {1}, estimated total time {2} -index_recs_completed = translate: Completed {0} out of {1} index records. - -fatal_error = translate: Fatal Error -fatal_error_detected = translate: {0} detected a fatal error during startup. -warning = translate: Warning -warnings_issued = translate: {0} issued warnings during startup. -startup_trace = translate: Startup trace -full_list_startup = translate: The full list of startup events and messages. -startup_status = translate: Startup Status -continue = translate: Continue - -# -# contact form templates ( /templates/freemarker/body/contactForm ) -# -rejected_spam = translate: REJECTED - SPAM -feedback_thanks_heading = translate: Thank you for your feedback -feedback_thanks_text = translate: Thank you for contacting our curation and development team. We will respond to your inquiry as soon as possible. -return_to_the = translate: Return to the -home_page = translate: home page -from = translate: From -ip_address = translate: IP address -viewing_page = translate: Likely viewing page -comments = translate: Comments -interest_thanks = translate: Thank you for your interest in {0}. Please submit this form with questions, comments, or feedback about the content of this site. -full_name = translate: Full name -comments_questions = translate: Comments, questions, or suggestions -enter_in_security_field = translate: Please enter the letters displayed below into the security field -send_mail = translate: Send Mail - -# -# display edit template ( /templates/freemarker/body/displayEdit ) -# -display_admin_header = translate: Display Admin and Configuration - -# -# error templates ( /templates/freemarker/body/error ) -# -we_have_an_error = translate: There was an error in the system. -error_was_reported = translate: This error has been reported to the site administrator. -error_message = translate: Error message -stack_trace = translate: Stack trace -trace_available = translate: full trace available in the vivo log -caused_by = translate: Caused by -requested_url = translate: Requested url -error_occurred = translate: An error occurred on the VIVO site -error_occurred_at = translate: An error occurred on your VIVO site at {0}. - -# -# login templates ( /templates/freemarker/body/login ) -# -internal_login = translate: Internal Login -no_email_supplied = translate: No email supplied. -no_password_supplied = translate: No password supplied. -logins_temporarily_disabled = translate: User logins are temporarily disabled while the system is being maintained. -incorrect_email_password = translate: Email or Password was incorrect. -password_length = translate: Password must be between 6 and 12 characters. -password_mismatch = translate: Passwords do not match. -new_pwd_matches_existing = translate: Your new password must be different from your existing password. -enter_email_pasword = translate: Enter the email address and password for your internal Vitro account. -change_password = translate: You must change your password to log in. -new_password = translate: New Password -confirm_password = translate: Confirm Password -email_capitalized = translate: Email -password_capitalized = translate: Password -login_button = translate: Log in -fake_external_auth = translate: Fake External Authentication -enter_id_to_login = translate: Enter the userID that you want to sign in as, or click Cancel. -username = translate: Username -submit_button = translate: Submit +confirm_delete = ¿Seguro que quiere borrar esta foto? \ No newline at end of file From 62f2074dc983d358f19651baccdb08f6afac7375 Mon Sep 17 00:00:00 2001 From: tworrall Date: Tue, 14 May 2013 11:04:04 -0400 Subject: [PATCH 16/18] updated the adjustFontSize function to include more checks --- .../js/individual/propertyGroupControls.js | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/webapp/web/js/individual/propertyGroupControls.js b/webapp/web/js/individual/propertyGroupControls.js index 6da441d5f..f71dc4daf 100644 --- a/webapp/web/js/individual/propertyGroupControls.js +++ b/webapp/web/js/individual/propertyGroupControls.js @@ -5,7 +5,7 @@ $(document).ready(function(){ $.extend(this, individualLocalName); adjustFontSize(); padSectionBottoms(); - retrieveLocalStorage(); + checkLocationHash(); // ensures that shorter property group sections don't cause the page to "jump around" // when the tabs are clicked @@ -59,6 +59,43 @@ $(document).ready(function(){ }); } + // If users click a marker on the home page map, they are taken to the profile + // page of the corresponding country. The url contains the word "Research" in + // the location hash. Use this to select the Research tab, which displays the + // researchers who have this countru as a geographic focus. + function checkLocationHash() { + if ( location.hash ) { + // remove the trailing white space + location.hash = location.hash.replace(/\s+/g, ''); + if ( location.hash.indexOf("map") >= 0 ) { + // get the name of the group that contains the geographicFocusOf property. + var tabName = $('h3#geographicFocusOf').parent('article').parent('div').attr("id"); + tabName = tabName.replace("Group",""); + tabNameCapped = tabName.charAt(0).toUpperCase() + tabName.slice(1); + // if the name of the first tab section = tabName we don't have to do anything; + // otherwise, select the correct tab and deselect the first one + var $firstTab = $('li.clickable').first(); + if ( $firstTab.text() != tabNameCapped ) { + // select the correct tab + $('li[groupName="' + tabName + '"]').removeClass("nonSelectedGroupTab clickable"); + $('li[groupName="' + tabName + '"]').addClass("selectedGroupTab clickable"); + // deselect the first tab + $firstTab.removeClass("selectedGroupTab clickable"); + $firstTab.addClass("nonSelectedGroupTab clickable"); + $('section.property-group:visible').hide(); + // show the selected tab section + $('section#' + tabName).show(); + } + } + else { + retrieveLocalStorage(); + } + } + else { + retrieveLocalStorage(); + } + } + // Next two functions -- keep track of which property group tab was selected, // so if we return from a custom form or a related individual, even via the back button, // the same property group will be selected as before. @@ -96,15 +133,16 @@ $(document).ready(function(){ } function retrieveLocalStorage() { + var localName = this.individualLocalName; var selectedTab = amplify.store(individualLocalName); if ( selectedTab != undefined ) { var groupName = selectedTab[0]; - // unlikely, but it's possible a tab that was previously selected and stored won't be displayed - // because the object properties would have been deleted (in non-edit mode). So ensure that the tab in local - // storage has been rendered on the page. + // unlikely, but it's possible a tab that was previously selected and stored won't be + // displayed because the object properties would have been deleted (in non-edit mode). + // So ensure that the tab in local storage has been rendered on the page. if ( $("ul.propertyTabsList li[groupName='" + groupName + "']").length ) { // if the selected tab is the default first one, don't do anything if ( $('li.clickable').first().attr("groupName") != groupName ) { @@ -129,14 +167,14 @@ $(document).ready(function(){ } } // if there are so many tabs that they wrap to a second line, adjust the font size to - //prevent wrapping + // prevent wrapping function adjustFontSize() { var width = 0; $('ul.propertyTabsList li').each(function() { width += $(this).outerWidth(); }); if ( width < 922 ) { - var diff = 926-width; + var diff = 925-width; $('ul.propertyTabsList li:last-child').css('width', diff + 'px'); } else { @@ -156,19 +194,25 @@ $(document).ready(function(){ else if ( diff > 130 && diff < 175 ) { $('ul.propertyTabsList li').css('font-size', "0.8em"); } - else if ( diff > 175 && diff < 260 ) { + else if ( diff > 175 && diff < 240 ) { $('ul.propertyTabsList li').css('font-size', "0.73em"); } - else { + else if ( diff > 240 && diff < 280 ) { $('ul.propertyTabsList li').css('font-size', "0.7em"); } + else if ( diff > 280 && diff < 310 ) { + $('ul.propertyTabsList li').css('font-size', "0.675em"); + } + else { + $('ul.propertyTabsList li').css('font-size', "0.65em"); + } // get the new width var newWidth = 0 $('ul.propertyTabsList li').each(function() { newWidth += $(this).outerWidth(); }); - var newDiff = 926-newWidth; + var newDiff = 925-newWidth; $('ul.propertyTabsList li:last-child').css('width', newDiff + 'px'); } } From 63445aa2499726f3fef8992c6f3fe961722d0273 Mon Sep 17 00:00:00 2001 From: tworrall Date: Tue, 14 May 2013 11:32:50 -0400 Subject: [PATCH 17/18] the startupStatus-displayRaw template does not have access to the i18n freemarker variable, so backing those changes out --- .../body/admin/startupStatus-displayRaw.ftl | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/webapp/web/templates/freemarker/body/admin/startupStatus-displayRaw.ftl b/webapp/web/templates/freemarker/body/admin/startupStatus-displayRaw.ftl index 98fdbc700..ce638c1fb 100644 --- a/webapp/web/templates/freemarker/body/admin/startupStatus-displayRaw.ftl +++ b/webapp/web/templates/freemarker/body/admin/startupStatus-displayRaw.ftl @@ -1,10 +1,10 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> -<#-- - Template for the raw page that displays the StartupStatus if there +<#-- + Template for the raw page that displays the StartupStatus if there are warnings or errors. - "raw" because this template works outside of the usual framework, in + "raw" because this template works outside of the usual framework, in case the Freemarker context didn't initialize properly. This file can't even include a reference to an external CSS file, in case @@ -40,7 +40,7 @@ - ${i18n().startup_status} + Startup Status + <#if status.errorItems?has_content> -

    ${i18n().fatal_error}

    +

    Fatal error

    -

    ${i18n().fatal_error_detected(applicationName)}

    +

    ${applicationName} detected a fatal error during startup.