diff --git a/api-webapp/pom.xml b/api-webapp/pom.xml
index 4d46cab..8281356 100644
--- a/api-webapp/pom.xml
+++ b/api-webapp/pom.xml
@@ -144,6 +144,12 @@
jakarta.mail
1.6.7
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
org.pac4j
diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/TranslationTool.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/TranslationTool.kt
index e3937d9..2c0fd63 100644
--- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/TranslationTool.kt
+++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/TranslationTool.kt
@@ -21,6 +21,14 @@ class TranslationTool {
}.let { Pair(iso, it) }
}
+ val defaultCountry = Translator.providedLanguages.associate { iso ->
+ when (iso) {
+ "en" -> "gb"
+ "zh" -> "cn"
+ else -> iso
+ }.let { Pair(iso, it) }
+ }
+
fun url(request: HttpServletRequest, lang: String): String {
val out = StringBuilder()
out.append(request.requestURL.replaceFirst(Regex("://"), "://$lang/"))
@@ -29,7 +37,12 @@ class TranslationTool {
return out.toString()
}
+ fun datepickerLocale(language: String, locale: String) =
+ if (datepickerLocales.contains(locale)) locale
+ else language
+
companion object {
+ val datepickerLocales = setOf("ar-DZ", "ar", "ar-TN", "az", "bg", "bm", "bn", "br", "bs", "ca", "cs", "cy", "da", "de", "el", "en-AU", "en-CA", "en-GB", "en-IE", "en-NZ", "en-ZA", "eo", "es", "et", "eu", "fa", "fi", "fo", "fr-CH", "fr", "gl", "he", "hi", "hr", "hu", "hy", "id", "is", "it-CH", "it", "ja", "ka", "kk", "km", "ko", "lt", "lv", "me", "mk", "mn", "mr", "ms", "nl-BE", "nl", "no", "oc", "pl", "pt-BR", "pt", "ro", "ru", "si", "sk", "sl", "sq", "sr", "sr-latn", "sv", "sw", "ta", "tg", "th", "tk", "tr", "uk", "uz-cyrl", "uz-latn", "vi", "zh-CN", "zh-TW")
val translator = ThreadLocal()
}
}
\ No newline at end of file
diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LanguageFilter.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LanguageFilter.kt
index 80abcef..2581309 100644
--- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LanguageFilter.kt
+++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LanguageFilter.kt
@@ -2,8 +2,10 @@ package org.jeudego.pairgoth.web
import org.jeudego.pairgoth.util.Translator
import org.jeudego.pairgoth.util.Translator.Companion.defaultLanguage
+import org.jeudego.pairgoth.util.Translator.Companion.defaultLocale
import org.jeudego.pairgoth.util.Translator.Companion.providedLanguages
import org.jeudego.pairgoth.view.TranslationTool
+import java.util.*
import javax.servlet.Filter
import javax.servlet.FilterChain
import javax.servlet.FilterConfig
@@ -29,52 +31,56 @@ class LanguageFilter : Filter {
return
}
+ val match = langPattern.matchEntire(uri)
+ val askedLanguage = match?.groupValues?.get(1)
+ val target = match?.groupValues?.get(2) ?: uri
+
val reqLang = request.getAttribute("lang") as String?
if (reqLang != null) {
+ // this is a forwarded request, language and locale should already have been set
TranslationTool.translator.set(Translator.getTranslator(reqLang))
chain.doFilter(request, response)
} else {
- val match = langPattern.matchEntire(uri)
- val lang = match?.groupValues?.get(1)
- val target = match?.groupValues?.get(2) ?: uri
-
- if (lang != null && providedLanguages.contains(lang)) {
+ val (preferredLanguage, preferredLocale) = parseLanguageHeader(request)
+ if (askedLanguage != null && providedLanguages.contains(askedLanguage)) {
// the target URI contains a language we provide
- request.setAttribute("lang", lang)
+ request.setAttribute("lang", askedLanguage)
+ request.setAttribute("loc",
+ if (askedLanguage == preferredLanguage) preferredLocale
+ else askedLanguage
+ )
request.setAttribute("target", target)
filterConfig!!.servletContext.getRequestDispatcher(target).forward(request, response)
} else {
// the request must be redirected
- val preferredLanguage = getPreferredLanguage(request)
- val destination = if (lang != null) target else uri
+ val destination = if (askedLanguage != null) target else uri
response.sendRedirect("/${preferredLanguage}${destination}")
}
}
}
- private fun getPreferredLanguage(request: HttpServletRequest): String {
- var lang = request.session.getAttribute("lang") as String?
- if (lang == null) {
- parseLanguageHeader(request)
- lang = request.session.getAttribute("lang") as String?
- }
- return lang ?: defaultLanguage
- }
-
- private fun parseLanguageHeader(request: HttpServletRequest) {
+ /**
+ * Returns Pair(language, locale)
+ */
+ private fun parseLanguageHeader(request: HttpServletRequest): Pair {
langHeaderParser.findAll(request.getHeader("Accept-Language") ?: "").filter {
providedLanguages.contains(it.groupValues[1])
}.sortedByDescending {
it.groupValues[3].toDoubleOrNull() ?: 1.0
- }.firstOrNull()?.let {
- it.groupValues[1]
+ }.firstOrNull()?.let { match ->
+ val lang = match.groupValues[1].let { if (it == "*") defaultLanguage else it }
+ val variant = match.groupValues.getOrNull(2)?.lowercase(Locale.ROOT)
+ // by convention, the variant is only kept if different from the language (fr-FR => fr)
+ val locale = variant?.let { if (lang == variant) lang else "$lang-${variant.uppercase(Locale.ROOT)}" } ?: lang
+ return Pair(lang, locale)
}
+ return Pair(defaultLanguage, defaultLanguage)
}
override fun destroy() {}
companion object {
private val langPattern = Regex("/([a-z]{2})(/.+)")
- private val langHeaderParser = Regex("(?:\\b(\\*|[a-z]{2})(?:(?:_|-)\\w+)?)(?:;q=([0-9.]+))?") ADD locale group captue
+ private val langHeaderParser = Regex("(?:\\b(\\*|[a-z]{2})(?:(?:_|-)(\\w+))?)(?:;q=([0-9.]+))?")
}
}
diff --git a/view-webapp/src/main/webapp/WEB-INF/layouts/standard.html b/view-webapp/src/main/webapp/WEB-INF/layouts/standard.html
index bdfdd80..662700e 100644
--- a/view-webapp/src/main/webapp/WEB-INF/layouts/standard.html
+++ b/view-webapp/src/main/webapp/WEB-INF/layouts/standard.html
@@ -70,6 +70,7 @@
-
+
+#if($datepickerLocale != 'en')
+
+#end
+