From b228a0aa4461aabac2656d532b7caee75463ade9 Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 15 Apr 2021 15:47:43 +0100 Subject: [PATCH] Use index of the supported tags to choose user lang (#15452) (#15488) Backport #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. Co-authored-by: Naohisa Murakami --- modules/translation/translation.go | 16 +++++++++------- modules/web/middleware/locale.go | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/translation/translation.go b/modules/translation/translation.go index b7276e53c0149..a03c036ab7e84 100644 --- a/modules/translation/translation.go +++ b/modules/translation/translation.go @@ -27,8 +27,9 @@ type LangType struct { } var ( - matcher language.Matcher - allLangs []LangType + matcher language.Matcher + allLangs []LangType + supportedTags []language.Tag ) // AllLangs returns all supported langauages @@ -51,12 +52,12 @@ func InitLocales() { } } - tags := make([]language.Tag, len(setting.Langs)) + supportedTags = make([]language.Tag, len(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 { key := "locale_" + setting.Langs[i] + ".ini" if err = i18n.SetMessageWithDesc(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil { @@ -79,8 +80,9 @@ func InitLocales() { } // Match matches accept languages -func Match(tags ...language.Tag) (tag language.Tag, index int, c language.Confidence) { - return matcher.Match(tags...) +func Match(tags ...language.Tag) language.Tag { + _, i, _ := matcher.Match(tags...) + return supportedTags[i] } // locale represents the information of localization. diff --git a/modules/web/middleware/locale.go b/modules/web/middleware/locale.go index a08e5aaeec7a1..ede38ef933c03 100644 --- a/modules/web/middleware/locale.go +++ b/modules/web/middleware/locale.go @@ -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. if len(lang) == 0 { tags, _, _ := language.ParseAcceptLanguage(req.Header.Get("Accept-Language")) - tag, _, _ := translation.Match(tags...) + tag := translation.Match(tags...) lang = tag.String() }