diff options
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/site/html.go | 28 | ||||
| -rw-r--r-- | cmd/site/locale.go | 97 | ||||
| -rw-r--r-- | cmd/site/main.go | 5 |
3 files changed, 129 insertions, 1 deletions
diff --git a/cmd/site/html.go b/cmd/site/html.go index ba304c5..d85e817 100644 --- a/cmd/site/html.go +++ b/cmd/site/html.go @@ -7,6 +7,7 @@ import ( "net/http" "time" + "github.com/Unknwon/i18n" "github.com/Xe/ln" ) @@ -21,7 +22,32 @@ func (s *Site) renderTemplatePage(templateFname string, data interface{}) http.H s.tlock.RLock() defer s.tlock.RUnlock() - var t *template.Template + const fallbackLang = `en-US` + + getTranslation := func(group, key string, vals ...interface{}) string { + var lang string + locale, err := GetPreferredLocale(r) + if err != nil { + ln.Error(r.Context(), err) + lang = fallbackLang + goto skip + } + + if !i18n.IsExist(locale.Lang) { + lang = fallbackLang + goto skip + } + + lang = locale.Lang + skip: + return i18n.Tr(lang, group+"."+key, vals...) + } + + funcMap := template.FuncMap{ + "trans": getTranslation, + } + + var t = template.New(templateFname).Funcs(funcMap) var err error if s.templates[templateFname] == nil { diff --git a/cmd/site/locale.go b/cmd/site/locale.go new file mode 100644 index 0000000..a65034a --- /dev/null +++ b/cmd/site/locale.go @@ -0,0 +1,97 @@ +package main + +import ( + "errors" + "net/http" + "strconv" + "strings" +) + +// Locale is locale value from the Accept-Language header in request +type Locale struct { + Lang, Country string + Qual float64 +} + +// Name returns the locale value in 'lang' or 'lang_country' format +// eg: de_DE, en_US, gb +func (l *Locale) Name() string { + if len(l.Country) > 0 { + return l.Lang + "_" + l.Country + } + return l.Lang +} + +// ParseLocale creates a Locale from a locale string +func ParseLocale(locale string) Locale { + locsplt := strings.Split(locale, "_") + resp := Locale{} + resp.Lang = locsplt[0] + if len(locsplt) > 1 { + resp.Country = locsplt[1] + } + return resp +} + +const ( + acceptLanguage = "Accept-Language" +) + +func supportedLocales(alstr string) []Locale { + locales := make([]Locale, 0) + alstr = strings.Replace(alstr, " ", "", -1) + if alstr == "" { + return locales + } + al := strings.Split(alstr, ",") + for _, lstr := range al { + locales = append(locales, Locale{ + Lang: parseLang(lstr), + Country: parseCountry(lstr), + Qual: parseQual(lstr), + }) + } + return locales +} + +// GetLocales returns supported locales for the given requet +func GetLocales(r *http.Request) []Locale { + return supportedLocales(r.Header.Get(acceptLanguage)) +} + +// GetPreferredLocale return preferred locale for the given reuqest +// returns error if there is no preferred locale +func GetPreferredLocale(r *http.Request) (*Locale, error) { + locales := GetLocales(r) + if len(locales) == 0 { + return &Locale{}, errors.New("No locale found") + } + return &locales[0], nil +} + +func parseLang(val string) string { + locale := strings.Split(val, ";")[0] + lang := strings.Split(locale, "-")[0] + return lang +} + +func parseCountry(val string) string { + locale := strings.Split(val, ";")[0] + spl := strings.Split(locale, "-") + if len(spl) > 1 { + return spl[1] + } + return "" +} + +func parseQual(val string) float64 { + spl := strings.Split(val, ";") + if len(spl) > 1 { + qual, err := strconv.ParseFloat(strings.Split(spl[1], "=")[1], 64) + if err != nil { + return 1 + } + return qual + } + return 1 +} diff --git a/cmd/site/main.go b/cmd/site/main.go index fa4b9b8..1bc5f71 100644 --- a/cmd/site/main.go +++ b/cmd/site/main.go @@ -12,6 +12,7 @@ import ( "sync" "time" + "github.com/Unknwon/i18n" "github.com/Xe/jsonfeed" "github.com/Xe/ln" "github.com/gorilla/feeds" @@ -62,6 +63,10 @@ func Build() (*Site, error) { Date string } + i18n.SetMessage("en-US", "conf/locale/locale_en-US.ini") + i18n.SetMessage("toki", "conf/locale/locale_toki.ini") + i18n.SetDefaultLang("en-US") + s := &Site{ rssFeed: &feeds.Feed{ Title: "Christine Dodrill's Blog", |
