Use index of the supported tags to choose user lang (#15452)

Fix #14793.

The previous implementation used the first return value of matcher.Match, which is the chosen language tag but may contain extensions such as de-DE-u-rg-chzzzz.

As mentioned in the documentation of language package, matcher.Match also returns the index of the supported tags, so I think it is better to use it rather than manipulate the returned language tag.
release/v1.15
Naohisa Murakami 2021-04-15 03:52:01 +09:00 committed by GitHub
parent 078df7a392
commit 1426601cf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 8 deletions

View File

@ -27,6 +27,7 @@ type LangType struct {
var ( var (
matcher language.Matcher matcher language.Matcher
allLangs []LangType allLangs []LangType
supportedTags []language.Tag
) )
// AllLangs returns all supported langauages // AllLangs returns all supported langauages
@ -50,12 +51,12 @@ func InitLocales() {
} }
} }
tags := make([]language.Tag, len(setting.Langs)) supportedTags = make([]language.Tag, len(setting.Langs))
for i, lang := range setting.Langs { for i, lang := range setting.Langs {
tags[i] = language.Raw.Make(lang) supportedTags[i] = language.Raw.Make(lang)
} }
matcher = language.NewMatcher(tags) matcher = language.NewMatcher(supportedTags)
for i := range setting.Names { for i := range setting.Names {
key := "locale_" + setting.Langs[i] + ".ini" key := "locale_" + setting.Langs[i] + ".ini"
if err = i18n.SetMessageWithDesc(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil { if err = i18n.SetMessageWithDesc(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil {
@ -73,8 +74,9 @@ func InitLocales() {
} }
// Match matches accept languages // Match matches accept languages
func Match(tags ...language.Tag) (tag language.Tag, index int, c language.Confidence) { func Match(tags ...language.Tag) language.Tag {
return matcher.Match(tags...) _, i, _ := matcher.Match(tags...)
return supportedTags[i]
} }
// locale represents the information of localization. // locale represents the information of localization.

View File

@ -38,7 +38,7 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale {
// The first element in the list is chosen to be the default language automatically. // The first element in the list is chosen to be the default language automatically.
if len(lang) == 0 { if len(lang) == 0 {
tags, _, _ := language.ParseAcceptLanguage(req.Header.Get("Accept-Language")) tags, _, _ := language.ParseAcceptLanguage(req.Header.Get("Accept-Language"))
tag, _, _ := translation.Match(tags...) tag := translation.Match(tags...)
lang = tag.String() lang = tag.String()
} }