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",
diff --git a/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini
similarity index 100%
rename from locale/locale_en-US.ini
rename to conf/locale/locale_en-US.ini
diff --git a/locale/locale_jbo-latn-us.ini b/conf/locale/locale_jbo-latn-us.ini
similarity index 100%
rename from locale/locale_jbo-latn-us.ini
rename to conf/locale/locale_jbo-latn-us.ini
diff --git a/locale/locale_toki.ini b/conf/locale/locale_toki.ini
similarity index 100%
rename from locale/locale_toki.ini
rename to conf/locale/locale_toki.ini
diff --git a/go.mod b/go.mod
index e6cd435..ab2a4af 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,7 @@
module github.com/Xe/site
require (
+ github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966 // indirect
github.com/Xe/gopreload v0.0.0-20170326043426-a00a8beb369c
github.com/Xe/jsonfeed v0.0.0-20170520170432-e21591505612
github.com/Xe/ln v0.0.0-20170921000907-466e05b2ef3e
@@ -17,5 +18,6 @@ require (
github.com/stretchr/testify v1.2.2 // indirect
github.com/tj/front v0.0.0-20170212063142-739be213b0a1
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
+ gopkg.in/ini.v1 v1.39.0 // indirect
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 // indirect
)
diff --git a/go.sum b/go.sum
index 5b12dc9..5d0bf3d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966 h1:Mp8GNJ/tdTZIEdLdZfykEJaL3mTyEYrSzYNcdoQKpJk=
+github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966/go.mod h1:SFtfq0zFPsENI7DpE87QM2hcYu5QQ0fRdCgP+P1Hrqo=
github.com/Xe/gopreload v0.0.0-20170326043426-a00a8beb369c h1:lqTJqaoonxgJMvvfl1ukr/3qCEGWC0nQxzPezbJrhHs=
github.com/Xe/gopreload v0.0.0-20170326043426-a00a8beb369c/go.mod h1:0aSWHJguPNHo6zlU7A4Ktua1A/VUr5Jdr1QZ2amOkAQ=
github.com/Xe/jsonfeed v0.0.0-20170520170432-e21591505612 h1:5cPld6YTMozzm3lK9VCnOErgoFbADM2hZc4KDu0YNKs=
@@ -33,5 +35,7 @@ github.com/tj/front v0.0.0-20170212063142-739be213b0a1 h1:lA+aPRvltlx2fwv/BnxyYS
github.com/tj/front v0.0.0-20170212063142-739be213b0a1/go.mod h1:deJrtusCTptAW4EUn5vBLpl3dhNqPqUwEjWJz5UNxpQ=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/ini.v1 v1.39.0 h1:Jf2sFGT+sAd7i+4ftUN1Jz90uw8XNH8NXbbOY16taA8=
+gopkg.in/ini.v1 v1.39.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=