Merge pull request #351 from chenejac/supportingPrivateTags

[3800 i18n redesign] Supporting private tags
This commit is contained in:
Georgy Litvinov 2022-12-13 16:50:02 +01:00 committed by GitHub
commit f548908b32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 58 additions and 24 deletions

View file

@ -170,7 +170,7 @@ public class ViewLabelsServlet extends FreemarkerHttpServlet{
Locale currentLocale) throws FileNotFoundException {
HashMap<String, String> map = new HashMap<String, String>();
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
map.put("code", locale.toString().replace("_", "-"));
map.put("code", locale.toLanguageTag().replace("_", "-"));
map.put("label", locale.getDisplayName(currentLocale));
return map;
}

View file

@ -464,7 +464,7 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen
Locale currentLocale) throws FileNotFoundException {
HashMap<String, String> map = new HashMap<String, String>();
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
map.put("code", locale.toString().replace("_", "-"));
map.put("code", locale.toLanguageTag().replace("_", "-"));
map.put("label", locale.getDisplayName(currentLocale));
return map;
}

View file

@ -284,7 +284,7 @@ public class CachingResponseFilter implements Filter {
StringBuilder buffer = new StringBuilder("\"").append(rawEtag);
for (Locale locale : locales) {
buffer.append(locale.toString());
buffer.append(locale.toLanguageTag());
}
buffer.append("\"");

View file

@ -88,7 +88,7 @@ public class LocaleSelectionController extends HttpServlet {
if (!selectables.contains(locale)) {
log.warn("User selected a locale '" + locale
+ "' that was not in the list: " + selectables);
} else if (!LocaleUtils.isAvailableLocale(locale)) {
} else if (!LocaleUtils.isAvailableLocale(locale.stripExtensions())) {
log.warn("User selected an unrecognized locale: '" + locale + "'");
}

View file

@ -3,12 +3,7 @@
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -36,7 +31,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
* { [a map for each Locale]
* code = [the code for the Locale, e.g. "en_US"]
* label = [the alt text for the Locale, e.g. "Spanish (Spain)"]
* imageUrl = [the URL of the image that represents the Locale]
* country = [the country for the Locale, e.g. "United States"]
* institution = [the abbreviation for institution, e.g. "UQAM"]
* selected = [true, if this locale is currently selected]
* }
* }
@ -50,6 +46,8 @@ public class LocaleSelectionDataGetter implements DataGetter {
private final VitroRequest vreq;
private static final char PRIVATE_USE_SUBTAG = 'x';
public LocaleSelectionDataGetter(VitroRequest vreq) {
this.vreq = vreq;
}
@ -73,10 +71,23 @@ public class LocaleSelectionDataGetter implements DataGetter {
private List<Map<String, Object>> buildLocalesList(List<Locale> selectables) {
Locale currentLocale = SelectedLocale.getCurrentLocale(vreq);
// The next couple of lines check whether there are locales in the list with the same root.
// If yes, the institution abbreviation (private tag) will be displayed in UI.
// For instance, if there are fr_CA_x_uqam and fr_CA in a VIVO instance runtime.properties,
// the institutional abbreviation (UQAM) will be displayed next to locale name
// in the dropdown menu for selection of a UI language.
boolean includeAbbreviation = false;
Set<String> setOfLocalesBase = new HashSet<>();
for(final Locale locale: selectables) {
setOfLocalesBase.add(locale.stripExtensions().toLanguageTag());
}
if (setOfLocalesBase.size() < selectables.size()) {
includeAbbreviation = true;
}
List<Map<String, Object>> list = new ArrayList<>();
for (Locale locale : selectables) {
try {
list.add(buildLocaleMap(locale, currentLocale));
list.add(buildLocaleMap(locale, currentLocale, includeAbbreviation));
} catch (FileNotFoundException e) {
log.warn("Can't show the Locale selector for '" + locale
+ "': " + e);
@ -86,12 +97,15 @@ public class LocaleSelectionDataGetter implements DataGetter {
}
private Map<String, Object> buildLocaleMap(Locale locale,
Locale currentLocale) throws FileNotFoundException {
Locale currentLocale, boolean includeAbbreviation) throws FileNotFoundException {
Map<String, Object> map = new HashMap<>();
map.put("code", locale.toLanguageTag().replace('-','_'));
map.put("label", locale.getDisplayLanguage(locale));
map.put("country", locale.getDisplayCountry(locale));
if (includeAbbreviation) {
map.put("institution", Optional.ofNullable(locale.getExtension(LocaleSelectionDataGetter.PRIVATE_USE_SUBTAG)).orElse("").toUpperCase());
}
map.put("selected", currentLocale.equals(locale));
return map;
}

View file

@ -154,7 +154,7 @@ public class LocaleSelectionSetup implements ServletContextListener {
Locale locale = LocaleUtility.languageStringToLocale(localeString);
if (!"es_GO".equals(localeString) && // No complaint about bogus locale
!LocaleUtils.isAvailableLocale(locale)) {
!LocaleUtils.isAvailableLocale(locale.stripExtensions())) {
ssWarning("'" + locale + "' is not a recognized locale.");
}

View file

@ -33,7 +33,7 @@ public class LanguageFilteringUtils {
* (as in RDF language specifiers).
*/
public static String localeToLanguage(Locale locale) {
return locale.toString().replace(UNDERSCORE, HYPHEN);
return locale.toLanguageTag().replace(UNDERSCORE, HYPHEN);
}
/**
@ -69,7 +69,7 @@ public class LanguageFilteringUtils {
List<String> langs = new ArrayList<>();
while (locales.hasMoreElements()) {
Locale locale = (Locale) locales.nextElement();
langs.add(locale.toString().replace(UNDERSCORE, HYPHEN));
langs.add(locale.toLanguageTag().replace(UNDERSCORE, HYPHEN));
}
if (!langs.contains(DEFAULT_LANG_STRING)) {
langs.add(DEFAULT_LANG_STRING);

View file

@ -136,7 +136,19 @@ public class RDFFilesLoader {
// Which locales are enabled in runtime.properties?
List<Locale> locales = SelectedLocale.getSelectableLocales(ctx);
for (Locale locale : locales) {
enabledLocales.add(locale.toLanguageTag().replace('-', '_'));
String localeString = locale.toLanguageTag().replace('-', '_');
if (! enabledLocales.contains(localeString)) {
enabledLocales.add(localeString);
}
// If a locale with fr_CA_x_uqam is used, the locale fr_CA should be also enabled for loading.
// Private tags (lang_CountryCode_x_InstitutionAbbreviation) are inteded to be just extension,
// therefore the basic locale (lang_CountryCode) should be loaded as well.
if(locale.hasExtensions()){
localeString = locale.stripExtensions().toLanguageTag().replace('-', '_');
if (! enabledLocales.contains(localeString)) {
enabledLocales.add(localeString);
}
}
}
// If no languages were enabled in runtime.properties, add a fallback as the default

View file

@ -10,10 +10,17 @@ public final class LocaleUtility {
public static Locale languageStringToLocale(String localeString){
String[] parsedLoc = localeString.trim().split("_", -1);
//regex pattern for locale tag with script specified
Locale locale = localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}") ?
new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).build() :
LocaleUtils.toLocale(localeString);
Locale locale = null;
if (localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}_x_[a-z]{1,}")) { //regex pattern for locale tag with script and private-use subtag, e.g. sr_Latn_RS_x_uns
locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).setExtension('x', parsedLoc[4]).build();
} else if (localeString.matches("^[a-z]{1,3}_[A-Za-z]{2}_x_[a-z]{1,}")) { //regex pattern for locale tag with script and private-use subtag, e.g. fr_CA_x_uqam
locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[1]).setExtension('x', parsedLoc[3]).build();
} else if (localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}")) { //regex pattern for locale tag with script specified, e.g. sr_Latn_RS
locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).build();
} else { // other, just languge, e.g. es, or language + region, e.g. en_US, pt_BR, ru_RU, etc.
locale = LocaleUtils.toLocale(localeString);
}
String localeLang = locale.toLanguageTag();
return locale;
}
}

View file

@ -209,11 +209,11 @@ public class SearchQueryUtils {
}
public static String getSortFieldNameForLocale(Locale locale) {
return locale.toString().replace('_', '-') + VitroSearchTermNames.LABEL_SORT_SUFFIX;
return locale.toLanguageTag().replace('_', '-') + VitroSearchTermNames.LABEL_SORT_SUFFIX;
}
public static String getLabelFieldNameForLocale(Locale locale) {
return locale.toString().replace('_', '-') + VitroSearchTermNames.LABEL_DISPLAY_SUFFIX;
return locale.toLanguageTag().replace('_', '-') + VitroSearchTermNames.LABEL_DISPLAY_SUFFIX;
}
public static SearchQuery getRandomQuery(List<String> vclassUris, int page, int pageSize){

View file

@ -6,7 +6,7 @@
<#list selectLocale.locales as locale>
<li <#if locale.selected>status="selected"</#if>>
<a href="${selectLocale.selectLocaleUrl}?selection=${locale.code}" title="${i18n().select_locale} -- ${locale.label}">${locale.label?capitalize}<#if locale.country?has_content> (${locale.country})</#if></a>
<a href="${selectLocale.selectLocaleUrl}?selection=${locale.code}" title="${i18n().select_locale} -- ${locale.label}">${locale.label?capitalize}<#if locale.country?has_content> (${locale.country})</#if><#if locale.institution?has_content> - ${locale.institution}</#if></a>
</li>
</#list>
</ul>
@ -21,6 +21,7 @@
* -- code
* -- label (tooltip displayed in original locale, not current locale)
* -- country (displayed in original locale, not current locale)
* -- institution (abbreviation)
* -- selected (boolean)
-->
<script type="text/javascript">