Add support of language tags composed of multiple sub-tags

This commit is contained in:
Bubka 2025-03-27 15:44:59 +01:00
parent 25de6e40f2
commit cd038384eb
59 changed files with 226 additions and 109 deletions

View File

@ -33,13 +33,12 @@ class SetLanguage
array_diff(explode(',', $accepted), ['*']),
function ($langs, $langItem) {
[$langLong, $weight] = array_merge(explode(';q=', $langItem), [1]);
$langShort = substr($langLong, 0, 2);
if (array_key_exists($langShort, $langs)) {
if ($langs[$langShort] < $weight) {
$langs[$langShort] = (float) $weight;
if (array_key_exists($langLong, $langs)) {
if ($langs[$langLong] < $weight) {
$langs[$langLong] = (float) $weight;
}
} else {
$langs[$langShort] = (float) $weight;
$langs[$langLong] = (float) $weight;
}
return $langs;
@ -56,6 +55,14 @@ class SetLanguage
$lang = $locale;
break;
}
// If the language tags pushed by the browser are composed of
// multiple subtags (ex: fr-FR) we need to retry but only with
// the "language subtag" (ex: fr)
$shortLocale = substr($locale, 0, 2);
if (in_array($shortLocale, $availableLocales)) {
$lang = $shortLocale;
break;
}
}
}

View File

@ -106,16 +106,21 @@ return [
*/
'locales' => [
'bg',
'zh-CN',
'da',
'nl',
'en',
'fr',
'de',
'zh',
'es',
'bg',
'ru',
'ja',
'hi',
'tr'
'it',
'ja',
'ko',
'pt-BR',
'ru',
'es-ES',
'tr',
],
/*

View File

@ -113,11 +113,13 @@ files: [
#
# Often software projects have custom names for the directories where translations are placed. crowdin-cli allows you to map your own languages to be understandable by Crowdin.
#
#"languages_mapping" : {
# "two_letters_code" : {
# "crowdin_language_code" : "local_name"
# }
#},
"languages_mapping" : {
"two_letters_code" : {
"zh-CN" : "zh-CN",
"pt-BR" : "pt-BR",
"es-ES" : "es-ES",
}
},
#
# Does the first line contain header?

2
resources/js/app.js vendored
View File

@ -32,7 +32,7 @@ app.use(router)
// Localization
app.use(i18nVue, {
lang: document.documentElement.lang.substring(0, 2),
lang: document.documentElement.lang,
resolve: async lang => {
const langs = import.meta.glob('../lang/*.json');
if (lang.includes('php_')) {

View File

@ -118,11 +118,24 @@ export const useUserStore = defineStore({
*/
applyLanguage() {
const { isSupported, language } = useNavigatorLanguage()
let lang = 'en'
if (isSupported) {
loadLanguageAsync(this.preferences.lang == 'browser' ? language.value.slice(0, 2) : this.preferences.lang)
if (this.preferences.lang == 'browser') {
if (this.$2fauth.langs.includes(language.value)) {
lang = language.value
}
// If the language tag pushed by the browser is composed of
// multiple subtags (ex: fr-FR) we need to retry but only with
// the "language subtag" (ex: fr)
else if (this.$2fauth.langs.includes(language.value.slice(0, 2))) {
lang = language.value.slice(0, 2)
}
}
else lang = this.preferences.lang
}
else loadLanguageAsync('en')
loadLanguageAsync(lang)
},
/**

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Browser preference',
'en' => 'English (English)',
'fr' => 'Français (French)',
'de' => 'Deutsch (German)',
'es' => 'Español (Spanish)',
'zh' => '简体中文 (Chinese Simplified)',
'ru' => 'Русский (Russian)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (Japanese)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (German)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japanese)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russian)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'По предпочитание на браузъра',
'en' => 'English (Английски)',
'fr' => 'Français (Френски)',
'de' => 'Deutsch (Немски)',
'es' => 'Español (Испански)',
'zh' => '简体中文 (Китайски опростен)',
'ru' => 'Русский (Руски)',
'bg' => 'Български (Български)',
'ja' => '日本語 (японски)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Немски)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (японски)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Руски)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Browser præference',
'en' => 'Engelsk (Engelsk)',
'fr' => 'Fransk (Fransk)',
'de' => 'Deutsch (tysk)',
'es' => 'Spansk ol (spansk)',
'zh' => 'Kinesisk (Forenklet)',
'ru' => 'Русский (Russisk)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (japansk)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (tysk)',
'hi' => '(Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (japansk)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russisk)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Tujórkcře (tyrkisk)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Browsereinstellung',
'en' => 'English (Englisch)',
'fr' => 'Français (Französisch)',
'de' => 'Deutsch (Deutsch)',
'es' => 'Español (Spanisch)',
'zh' => '简体中文 (Vereinfachtes Chinesisch)',
'ru' => 'Русский (Russisch)',
'bg' => 'Български (Bulgarisch)',
'ja' => '日本語 (Japanisch)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Deutsch)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japanisch)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russisch)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Preferencia del navegador',
'en' => 'English (Inglés)',
'fr' => 'Français (Francés)',
'de' => 'Deutsch (Alemán)',
'es' => 'Español',
'zh' => '简体中文 (Chino Simplificado)',
'ru' => 'Русский (ruso)',
'bg' => 'Български (Búlgaro)',
'ja' => '日本語 (Japonés)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Alemán)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japonés)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (ruso)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Préférence du navigateur',
'en' => 'English (Anglais)',
'fr' => 'Français (Français)',
'de' => 'Deutsch (Allemand)',
'es' => 'Español (Espagnol)',
'zh' => '简体中文 (Chinois simplifié)',
'ru' => 'Русский (russe)',
'bg' => 'Български (Bulgare)',
'ja' => '日本語 (Japonais)',
'zh-CN' => '简体中文 (Chinois simplifié)',
'da' => 'Dansk (Danois)',
'nl' => 'Nederlands (Néerlandais)',
'de' => 'Deutsch (Allemand)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italien)',
'ja' => '日本語 (Japonais)',
'ko' => '한국어 (Coréen)',
'pt-BR' => 'Português (Portugais, Brésilien)',
'ru' => 'Русский (russe)',
'es-ES' => 'Español (Espagnol)',
'tr' => 'Türkçe (Turc)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'ब्राउज़र की प्राथमिकता',
'en' => 'English (इंग्लिश)',
'fr' => 'Français (फ्रेंच)',
'de' => 'Deutsch (जर्मन)',
'es' => 'Español (स्पैनिश)',
'zh' => '简体中文 (सामान्य चीनी)',
'ru' => 'Русский (रशिअन)',
'bg' => 'Български (बुल्गेरियन)',
'ja' => '日本語 (जापानी)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (जर्मन)',
'hi' => 'हिंदी (हिंदी)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (जापानी)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (रशिअन)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Preferensi perambaan',
'en' => 'English (English)',
'fr' => 'Français (French)',
'de' => 'Deutsch (German)',
'es' => 'Español (Spanish)',
'zh' => '简体中文 (Chinese Simplified)',
'ru' => 'Русский (Russian)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (Japanese)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (German)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japanese)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russian)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Preferenza del browser',
'en' => 'English (Inglese)',
'fr' => 'Français (Francese)',
'de' => 'Deutsch (Tedesco)',
'es' => 'Español (Spagnolo)',
'zh' => '简体中文 (Cinese Semplificato)',
'ru' => 'Русский (russo)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (Giapponese)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Tedesco)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Giapponese)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (russo)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turco)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'ブラウザの設定',
'en' => 'English (英語)',
'fr' => 'Français (フランス語)',
'de' => 'Deutsch (ドイツ語)',
'es' => 'Español (スペイン語)',
'zh' => '简体中文 (簡体字中国語)',
'ru' => 'Русский (ロシア語)',
'bg' => 'Български (ブルガリア語)',
'ja' => '日本語 (日本語)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (ドイツ語)',
'hi' => 'हिंदी (ヒンディー語)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (日本語)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (ロシア語)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (トルコ語)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => '브라우저 설정',
'en' => 'English (영어)',
'fr' => 'Français (프랑스어)',
'de' => 'Deutsch (독일어)',
'es' => 'Español (스페인어)',
'zh' => '简体中文 (중국어 간체)',
'ru' => 'Pусский (러시아어)',
'bg' => 'Български (불가리아어)',
'ja' => '日本語 (일본어)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (독일어)',
'hi' => 'हिंदी (힌디어)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (일본어)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Pусский (러시아어)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (튀르키예어)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Browser voorkeuren',
'en' => 'Engels (English)',
'fr' => 'Frans (French)',
'de' => 'Duits (Deutsch)',
'es' => 'Spaans (Español)',
'zh' => 'Chinees (Vereenvoudigd Chinees)',
'ru' => 'Русский (Russisch)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (Japans)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Duits (Deutsch)',
'hi' => 'barometertels ½ (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japans)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russisch)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Turk (Turks)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Preferencje przeglądarki',
'en' => 'Angielski (język angielski)',
'fr' => 'Français (French)',
'de' => 'Deutsch (German)',
'es' => 'Español (Spanish)',
'zh' => '简体中文 (Chinese Simplified)',
'ru' => 'Русский (Russian)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (Japanese)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (German)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japanese)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russian)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Padrão do navegador',
'en' => 'English (Inglês)',
'fr' => 'Français (Francês)',
'de' => 'Deutsch (Alemão)',
'es' => 'Español (Espanhol)',
'zh' => '简体中文 (Chinês Simplificado)',
'ru' => 'Русский (Russo)',
'bg' => 'Български (Búlgaro)',
'ja' => '日本語 (Japonês)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Alemão)',
'hi' => 'हिंदी (Indiano)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japonês)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russo)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turco)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Настройки браузера',
'en' => 'English (Английский)',
'fr' => 'Français (Французский)',
'de' => 'Deutsch (Немецкий)',
'es' => 'Español (Испанский)',
'zh' => '简体中文 (Китайский упрощенный)',
'ru' => 'Русский (Русский)',
'bg' => 'Български (Болгарский)',
'ja' => '日本語 (Японский)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Немецкий)',
'hi' => 'हिंदी (Хинди)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Японский)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Русский)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Турецкий)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Tarayıcı önayarı',
'en' => 'English (İngilizce)',
'fr' => 'Français (Fransızca)',
'de' => 'Deutsch (Almanca)',
'es' => 'Español (İspanyolca)',
'zh' => '简体中文 (Basitleştirilmiş Çince)',
'ru' => 'Русский (Rusça)',
'bg' => 'Български (Bulgarca)',
'ja' => '日本語 (Japonca)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (Almanca)',
'hi' => 'हिंदी (Hintçe)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japonca)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Rusça)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => 'Browser preference',
'en' => 'English (English)',
'fr' => 'Français (French)',
'de' => 'Deutsch (German)',
'es' => 'Español (Spanish)',
'zh' => '简体中文 (Chinese Simplified)',
'ru' => 'Русский (Russian)',
'bg' => 'Български (Bulgarian)',
'ja' => '日本語 (Japanese)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (German)',
'hi' => 'हिंदी (Hindi)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (Japanese)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (Russian)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
];

View File

@ -13,12 +13,17 @@ return [
'browser_preference' => '跟随浏览器语言',
'en' => 'English (英语)',
'fr' => 'Français (法语)',
'de' => 'Deutsch (德语)',
'es' => 'Español (西班牙语)',
'zh' => '中文 (简体中文)',
'ru' => 'Русский (俄语)',
'bg' => 'Български (保加利亚语)',
'ja' => '日本語 (日语)',
'zh-CN' => '简体中文 (Chinese Simplified)',
'da' => 'Dansk (Danish)',
'nl' => 'Nederlands (Dutch)',
'de' => 'Deutsch (德语)',
'hi' => 'हिंदी (印地语)',
'it' => 'Italiano (Italian)',
'ja' => '日本語 (日语)',
'ko' => '한국어 (Korean)',
'pt-BR' => 'Português (Portuguese, Brazilian)',
'ru' => 'Русский (俄语)',
'es-ES' => 'Español (Spanish)',
'tr' => 'Türkçe (土耳其语)',
];