[VIVO-1290] Multi-language improvements

* fix hard coded label "more..."

* fix hard coded label "pages"

* fix hard coded labels "pages" and "to"

* fix some hard coded page titles and messages

* show class names in list views corresponding to preferred languages

* translate page titles of search result page and login page
This commit is contained in:
grahamtriggs 2016-11-14 14:45:40 +00:00 committed by GitHub
commit b97ee8dd26
14 changed files with 107 additions and 45 deletions

View file

@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServ
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
/**
* Offer the user the ability to apply a RestrictedAuthenticator or revert to a
@ -80,7 +81,7 @@ public class RestrictLoginsController extends FreemarkerHttpServlet {
boolean restricted = figureCurrentlyState() == State.RESTRICTED;
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Restrict Logins");
body.put("title", I18n.text(vreq, "restrict_logins"));
body.put("restricted", restricted);
if (!MESSAGE_NO_MESSAGE.equals(messageCode)) {
body.put(messageCode, Boolean.TRUE);

View file

@ -11,6 +11,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
@ -27,7 +28,7 @@ public class StartupStatusController extends FreemarkerHttpServlet {
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Startup Status");
body.put("title", I18n.text(vreq, "startup_status"));
body.put("status", StartupStatus.getBean(getServletContext()));
body.put("contextPath", getContextPath());
body.put("applicationName", getApplicationName(vreq));

View file

@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Res
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
@ -94,7 +95,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
vclass.getURI(),
page,
alpha,
vreq.getWebappDaoFactory().getIndividualDao());
vreq);
body.putAll(vcResults.asFreemarkerMap());
List<Individual> inds = vcResults.getEntities();
@ -148,12 +149,12 @@ public class IndividualListController extends FreemarkerHttpServlet {
return SearchQueryUtils.getPageParameter(request);
}
public static IndividualListResults getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao)
public static IndividualListResults getResultsForVClass(String vclassURI, int page, String alpha, VitroRequest vreq)
throws SearchException{
try{
List<String> classUris = Collections.singletonList(vclassURI);
IndividualListQueryResults results = buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, indDao);
return getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
IndividualListQueryResults results = buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, vreq.getWebappDaoFactory().getIndividualDao());
return getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha, vreq);
} catch (SearchEngineException e) {
String msg = "An error occurred retrieving results for vclass query";
log.error(msg, e);
@ -165,31 +166,31 @@ public class IndividualListController extends FreemarkerHttpServlet {
}
}
public static IndividualListResults getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao) {
public static IndividualListResults getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, VitroRequest vreq) {
try{
IndividualListQueryResults results = buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, indDao);
return getResultsForVClassQuery(results, page, pageSize, alpha);
IndividualListQueryResults results = buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, vreq.getWebappDaoFactory().getIndividualDao());
return getResultsForVClassQuery(results, page, pageSize, alpha, vreq);
} catch(Throwable th) {
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th);
return IndividualListResults.EMPTY;
}
}
public static IndividualListResults getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao) {
public static IndividualListResults getRandomResultsForVClass(String vclassURI, int page, int pageSize, VitroRequest vreq) {
try{
List<String> classUris = Collections.singletonList(vclassURI);
IndividualListQueryResults results = buildAndExecuteRandomVClassQuery(classUris, page, pageSize, indDao);
return getResultsForVClassQuery(results, page, pageSize, "");
IndividualListQueryResults results = buildAndExecuteRandomVClassQuery(classUris, page, pageSize, vreq.getWebappDaoFactory().getIndividualDao());
return getResultsForVClassQuery(results, page, pageSize, "", vreq);
} catch(Throwable th) {
log.error("An error occurred retrieving random results for vclass query", th);
return IndividualListResults.EMPTY;
}
}
private static IndividualListResults getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
private static IndividualListResults getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha, VitroRequest vreq) {
long hitCount = results.getHitCount();
if ( hitCount > pageSize ){
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, true, makePagesList(hitCount, pageSize, page));
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, true, makePagesList(hitCount, pageSize, page, vreq));
}else{
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, false, Collections.<PageRecord>emptyList());
}
@ -221,7 +222,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
}
public static List<PageRecord> makePagesList( long size, int pageSize, int selectedPage ) {
public static List<PageRecord> makePagesList( long size, int pageSize, int selectedPage , VitroRequest vreq) {
List<PageRecord> records = new ArrayList<PageRecord>( MAX_PAGES + 1 );
int requiredPages = (int) (size/pageSize) ;
@ -234,7 +235,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
for(int page = 1; page < requiredPages && page <= MAX_PAGES ; page++ ){
records.add( new PageRecord( "page=" + page, Integer.toString(page), Integer.toString(page), selectedPage == page ) );
}
records.add( new PageRecord( "page="+ (MAX_PAGES+1), Integer.toString(MAX_PAGES+1), "more...", false));
records.add( new PageRecord( "page="+ (MAX_PAGES+1), Integer.toString(MAX_PAGES+1), I18n.text(vreq, "paging_link_more"), false));
}else if( requiredPages > MAX_PAGES && selectedPage+1 > MAX_PAGES && selectedPage < requiredPages - MAX_PAGES){
//the selected pages is in the middle of the list of page
int startPage = selectedPage - MAX_PAGES / 2;
@ -242,7 +243,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
for(int page = startPage; page <= endPage ; page++ ){
records.add( new PageRecord( "page=" + page, Integer.toString(page), Integer.toString(page), selectedPage == page ) );
}
records.add( new PageRecord( "page="+ (endPage+1), Integer.toString(endPage+1), "more...", false));
records.add( new PageRecord( "page="+ (endPage+1), Integer.toString(endPage+1), I18n.text(vreq, "paging_link_more"), false));
}else if ( requiredPages > MAX_PAGES && selectedPage > requiredPages - MAX_PAGES ){
//the selected page is in the end of the list
int startPage = requiredPages - MAX_PAGES;

View file

@ -27,6 +27,7 @@ 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;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils;
/**
@ -188,23 +189,23 @@ public class PageController extends FreemarkerHttpServlet{
private ResponseValues doError(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title","Page could not be created");
body.put("errorMessage", "There was an error while creating the page, please check the logs.");
body.put("title", I18n.text(vreq, "page_not_created"));
body.put("errorMessage", I18n.text(vreq, "page_not_created_msg"));
return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
private ResponseValues doNotFound(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title","Page Not Found");
body.put("errorMessage", "The page was not found in the system.");
body.put("title", I18n.text(vreq, "page_not_found"));
body.put("errorMessage", I18n.text(vreq, "page_not_found_msg"));
return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_NOT_FOUND);
}
private ResponseValues doNoPageSpecified(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title","No page URI specified");
body.put("errorMessage", "Could not generate page beacause it was unclear what page was being requested. A URL mapping may be missing.");
body.put("title",I18n.text(vreq, "page_uri_missing"));
body.put("errorMessage", I18n.text(vreq, "page_uri_missing_msg"));
return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_NOT_FOUND);
}

View file

@ -5,12 +5,14 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
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.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
/*
* Servlet that only specifies a template, without putting any data
@ -33,7 +35,7 @@ public class StaticPageController extends FreemarkerHttpServlet {
String requestedUrl = vreq.getServletPath();
String title = null;
if (requestedUrl.equals("/login")) {
title = "Log in to " + siteName;
title = StringUtils.capitalize(I18n.text(vreq, "log_in")) + " - " + siteName;
}
return title;
}

View file

@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Exc
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.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
/**
* Handles requests for entity information.
@ -74,7 +75,7 @@ public class IndividualController extends FreemarkerHttpServlet {
* If we can't figure out what individual you want, or if there
* is no such individual, show an informative error page.
*/
return doNotFound();
return doNotFound(vreq);
case BYTESTREAM_REDIRECT:
/*
* If the Individual requested is a FileBytestream, redirect
@ -116,10 +117,10 @@ public class IndividualController extends FreemarkerHttpServlet {
new IndividualRequestAnalysisContextImpl(vreq)).analyze();
}
private ResponseValues doNotFound() {
private ResponseValues doNotFound(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Individual Not Found");
body.put("errorMessage", "The individual was not found in the system.");
body.put("title", I18n.text(vreq, "individual_not_found"));
body.put("errorMessage", I18n.text(vreq, "individual_not_found_msg"));
return new TemplateResponseValues(TEMPLATE_HELP, body,
HttpServletResponse.SC_NOT_FOUND);

View file

@ -109,7 +109,7 @@ public class JsonServlet extends VitroHttpServlet {
vclassURIs,
page, INDIVIDUALS_PER_PAGE,
alpha,
vreq.getWebappDaoFactory().getIndividualDao());
vreq);
} catch(Exception ex) {
log.error("Error in retrieval of search results for VClass " + vclassURIs.toString(), ex);
return IndividualListResults.EMPTY;
@ -144,7 +144,7 @@ public class JsonServlet extends VitroHttpServlet {
vclassURI,
page,
pageSize,
vreq.getWebappDaoFactory().getIndividualDao());
vreq);
} catch(Exception ex) {
log.error("Error in retrieval of search results for VClass " + vclassURI, ex);
return IndividualListResults.EMPTY;

View file

@ -868,6 +868,28 @@ public class JenaBaseDao extends JenaBaseDaoCon {
return label;
}
/**
* Searches for literal in preferred language.
* @param labels
* the literals to search; must not be null
* @return the literal in preferred language if its containing in given list;
* otherwise the first entry will returned; returns null if an empty list was given
*/
protected Literal tryLiteralForPreferredLanguages(List<Literal> labels) {
// search for literal of preferred language
for (Literal literal : labels) {
for (String lang : PREFERRED_LANGUAGES) {
if (lang.equals(literal.getLanguage())) {
return literal;
}
}
}
// return first literal as last resort
return 0 == labels.size() ? null : labels.get(0);
}
private Literal tryPropertyForPreferredLanguages( OntResource r, Property p, boolean alsoTryNoLang ) {
Literal label = null;
List<RDFNode> labels = r.listPropertyValues(p).toList();

View file

@ -7,7 +7,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
@ -17,6 +19,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.ontology.OntResource;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
@ -26,6 +29,7 @@ import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.QuerySolutionMap;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.Syntax;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
@ -503,7 +507,8 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
return Collections.emptyMap();
}
Map<String, String> types = new LinkedHashMap<String, String>();
Map<String, String> result = new LinkedHashMap<String, String>();
Map<String, List<Literal>> types = new LinkedHashMap<String, List<Literal>>();
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
@ -521,16 +526,24 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
}
RDFNode labelNode = soln.get("label");
String label = null;
if (labelNode.isLiteral()) {
label = labelNode.asLiteral().getLexicalForm();
if (StringUtils.isNotBlank(type) && labelNode.isLiteral()) {
List<Literal> langLabels = types.get(type);
if (null == langLabels) {
types.put(type, langLabels = new ArrayList<Literal>());
}
langLabels.add(labelNode.asLiteral());
}
}
if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(label)) {
types.put(type, label);
// choose labels corresponding to preferred languages
Set<Entry<String, List<Literal>>> typeEntries = types.entrySet();
for (Entry<String, List<Literal>> current : typeEntries) {
result.put(current.getKey(), tryLiteralForPreferredLanguages(current.getValue()).getLexicalForm());
}
}
return types;
return result;
} catch (Exception e) {
log.error("Error getting most specific types for subject " + subjectUri);

View file

@ -262,8 +262,8 @@ public class PagedSearchController extends FreemarkerHttpServlet {
.getIndividualTemplateModels(individuals, vreq));
body.put("querytext", queryText);
body.put("title", queryText + " - " + appBean.getApplicationName()
+ " Search Results");
body.put("title", new StringBuilder().append(appBean.getApplicationName()).append(" - ").
append(I18n.text(vreq, "search_results_for")).append(" '").append(queryText).append("'").toString());
body.put("hitCount", hitCount);
body.put("startIndex", startIndex);

View file

@ -177,7 +177,7 @@ public class SearchIndividualsDataGetter extends DataGetterBase implements DataG
vclass.getURI(),
page,
alpha,
vreq.getWebappDaoFactory().getIndividualDao());
vreq);
body.putAll(vcResults.asFreemarkerMap());
List<Individual> inds = vcResults.getEntities();

View file

@ -234,6 +234,7 @@ verbose_turn_off = Apagar
resource_uri = URI de recursos
individual_not_found = Individual no encontrado
individual_not_found_msg = El individuo no se encontró en el sistema.
entity_to_query_for = Este id es el identificador de la entidad para consultar. netid también funciona.
menu_ordering = Menú pedidos
@ -423,6 +424,13 @@ run_sdb_setup = Ejecutar la instalación SDB
unrecognized_user = Usuario no reconocido
no_individual_associated_with_id = Por alguna razón, no hay ninguna persona en VIVO que se asocia con su ID de red. Tal vez usted debería ponerse en contacto con el administrador de VIVO.
page_not_created = página no pudo ser creado
page_not_created_msg = Se ha producido un error al crear la página, por favor, compruebe los registros.
page_not_found = Página no encontrada
page_not_found_msg = La página no se ha encontrado en el sistema.
page_uri_missing = No se especifica la página URI
page_uri_missing_msg = No se pudo generar la página pd no estaba claro en qué página se está solicitando. Una asignación de dirección URL es posible que falte.
#
# site admin templates ( /templates/freemarker/body/siteAdmin )
#
@ -518,6 +526,8 @@ class_link = Enlace clase
previous = Anterior
page_link = enlace de la página
next_capitalized = Próximo
download_results = resultados de la transferencia directa
to = a
#
# shortview templates ( /templates/freemarker/body/partials/shortview )

View file

@ -246,6 +246,7 @@ verbose_turn_off = Turn off
resource_uri = Resource URI
individual_not_found = Individual not found
individual_not_found_msg = The individual was not found in the system.
entity_to_query_for = This id is the id of the entity to query for. netid also works.
menu_ordering = Menu Ordering
@ -435,6 +436,13 @@ run_sdb_setup = Run SDB Setup
unrecognized_user = Unrecognized user
no_individual_associated_with_id = For some reason, there is no individual in VIVO that is associated with your Net ID. Perhaps you should contact your VIVO administrator.
page_not_created = Page could not be created
page_not_created_msg = There was an error while creating the page, please check the logs.
page_not_found = Page Not Found
page_not_found_msg = The page was not found in the system.
page_uri_missing = No page URI specified
page_uri_missing_msg = Could not generate page beacause it was unclear what page was being requested. A URL mapping may be missing.
#
# site admin templates ( /templates/freemarker/body/siteAdmin )
#
@ -531,6 +539,8 @@ class_link = class link
previous = Previous
page_link = page link
next_capitalized = Next
download_results = Download Results
to = to
#
# shortview templates ( /templates/freemarker/body/partials/shortview )

View file

@ -20,7 +20,7 @@
var urlsBase = '${urls.base}';
</script>
<img id="downloadIcon" src="images/download-icon.png" alt="Download Results" title="Download Results" />
<img id="downloadIcon" src="images/download-icon.png" alt="${i18n().download_results}" title="${i18n().download_results}" />
<#-- <span id="downloadResults" style="float:left"></span> -->
</h2>
@ -42,7 +42,7 @@
<#if classLinks?has_content>
<div class="searchTOC">
<#if classGroupName?has_content>
<h4>${i18n().limit} ${classGroupName} to</h4>
<h4>${i18n().limit} ${classGroupName} ${i18n().to}</h4>
<#else>
<h4>${i18n().limit_to}</h4>
</#if>
@ -67,7 +67,7 @@
<#-- Paging controls -->
<#if (pagingLinks?size > 0)>
<div class="searchpages">
Pages:
${i18n().pages}:
<#if prevPage??><a class="prev" href="${prevPage}" title="${i18n().previous}">${i18n().previous}</a></#if>
<#list pagingLinks as link>
<#if link.url??>