func settingLocales() { // load locales with locale_LANG.ini files langs := "en-US|zh-CN" for _, lang := range strings.Split(langs, "|") { lang = strings.TrimSpace(lang) files := []interface{}{"conf/" + "locale_" + lang + ".ini"} if fh, err := os.Open(files[0].(string)); err == nil { fh.Close() } else { files = nil } if err := i18n.SetMessage(lang, "conf/global/"+"locale_"+lang+".ini", files...); err != nil { log.Error("Fail to set message file: " + err.Error()) os.Exit(2) } } Langs = i18n.ListLangs() }
// I18n is a middleware provides localization layer for your application. // Paramenter langs must be in the form of "en-US", "zh-CN", etc. // Otherwise it may not recognize browser input. func I18n(options ...Options) macaron.Handler { opt := prepareOptions(options) initLocales(opt) return func(ctx *macaron.Context) { isNeedRedir := false hasCookie := false // 1. Check URL arguments. lang := ctx.Query(opt.Parameter) // 2. Get language information from cookies. if len(lang) == 0 { lang = ctx.GetCookie("lang") hasCookie = true } else { isNeedRedir = true } // Check again in case someone modify by purpose. if !i18n.IsExist(lang) { lang = "" isNeedRedir = false hasCookie = false } // 3. Get language information from 'Accept-Language'. if len(lang) == 0 { al := ctx.Req.Header.Get("Accept-Language") if len(al) > 4 { al = al[:5] // Only compare first 5 letters. if i18n.IsExist(al) { lang = al } } } // 4. Default language is the first element in the list. if len(lang) == 0 { lang = i18n.GetLangByIndex(0) isNeedRedir = false } curLang := LangType{ Lang: lang, } // Save language information in cookies. if !hasCookie { ctx.SetCookie("lang", curLang.Lang, 1<<31-1, "/"+strings.TrimPrefix(opt.SubURL, "/")) } restLangs := make([]LangType, 0, i18n.Count()-1) langs := i18n.ListLangs() names := i18n.ListLangDescs() for i, v := range langs { if lang != v { restLangs = append(restLangs, LangType{v, names[i]}) } else { curLang.Name = names[i] } } // Set language properties. locale := Locale{i18n.Locale{lang}} ctx.Map(locale) ctx.Locale = locale ctx.Data[opt.TmplName] = locale ctx.Data["Tr"] = i18n.Tr ctx.Data["Lang"] = locale.Lang ctx.Data["LangName"] = curLang.Name ctx.Data["AllLangs"] = append([]LangType{curLang}, restLangs...) ctx.Data["RestLangs"] = restLangs if opt.Redirect && isNeedRedir { ctx.Redirect(opt.SubURL + ctx.Req.RequestURI[:strings.Index(ctx.Req.RequestURI, "?")]) } } }