commit 0ebcb67921492846dec4f77ec26d3f3677b36e14 Author: Darko Luketic Date: Mon Sep 5 15:20:48 2016 +0200 initial diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..5545377 --- /dev/null +++ b/README.md @@ -0,0 +1,106 @@ +# github.com/dalu/i18n + +Go middleware that utilizes https://github.com/nicksnyder/go-i18n + +## Required + +Go 1.7 for context-aware http Package + +## License + +BSD2 + +## Issues + +Use the Github issue tracker + +### Example + +```go +package main + +import ( + "net/http" + + "github.com/dalu/i18n" + "github.com/nicksnyder/go-i18n/i18n/bundle" +) + +func main() { + var hrHR = []byte(`[ + { + "id": "hello", + "translation": "Pozdrav na {{.Lang}}" + }, + { + "id": "coins", + "translation":{ + "one": "Imas {{.Count}} kunu", + "few": "Imas {{.Count}} kuna", + "other": "Imas {{.Count}} kuna" + } + } +]`) + + fb := make(map[string][]byte) + fb["hr-hr.all.json"] = hrHR + + imw := i18n.New(i18n.Config{ + DefaultLanguage: "en-us", + Files: []string{"files/en-us.all.json", "files/de-de.all.json"}, + FilesBytes: fb, + Debug: true, + URLParam: "lang", + }) + + http.Handle("/", imw.Middleware(http.HandlerFunc(indexHandler))) + http.ListenAndServe(":8080", nil) +} + +func indexHandler(w http.ResponseWriter, r *http.Request) { + lang := r.Context().Value("i18nlang").(string) + T := r.Context().Value("i18nTfunc").(bundle.TranslateFunc) + w.Write([]byte(T("hello", map[string]interface{}{"Lang":lang}))) + w.Write([]byte("\n")) + w.Write([]byte(T("coins", 1))) + w.Write([]byte("\n")) + w.Write([]byte(T("coins", 2))) + w.Write([]byte("\n")) + w.Write([]byte(T("coins", 200))) +} +``` + + +files/en-us.all.json +```json +[ + { + "id": "coins", + "translation": { + "one": "You have {{.Count}} coin", + "other": "You have {{.Count}} coins" + } + }, + { + "id": "hello", + "translation": "Hello in en-US" + } +] +``` + +files/de-de.all.json +```json +[ + { + "id": "coins", + "translation": { + "one": "Du hast {{.Count}} Münze", + "other": "Du hast {{.Count}} Münzen" + } + }, + { + "id": "hello", + "translation": "Hallo in {{.Lang}}" + } +] +``` \ No newline at end of file diff --git a/i18n.go b/i18n.go new file mode 100644 index 0000000..4e59dcd --- /dev/null +++ b/i18n.go @@ -0,0 +1,75 @@ +package i18n + +import ( + "log" + "github.com/nicksnyder/go-i18n/i18n/bundle" + "net/http" + "context" +) + +type Config struct { + DefaultLanguage string + Files []string // files to load + FilesBytes map[string][]byte // or slices of []bytes with the embedded file data + Debug bool + URLParam string + bundle *bundle.Bundle +} + +type I18nMiddleware struct { + config Config +} + +func New(c Config) *I18nMiddleware { + if c.DefaultLanguage == "" { + log.Fatal("i18n: No default language set") + } + if len(c.Files) == 0 && len(c.FilesBytes) == 0 { + log.Fatal("i18n: You need to supply either Config.Files and|or Config.FileBytes for language files to be loaded|parsed") + } + + b := bundle.New() + c.bundle = b + + for _, file := range c.Files { + if e := b.LoadTranslationFile(file); e != nil { + log.Fatal("i18n:", e.Error()) + } + } + for s, by := range c.FilesBytes { + if e := b.ParseTranslationFileBytes(s, by); e != nil { + log.Fatal("i18n:", e.Error()) + } + } + + if c.Debug { + log.Println("i18n: Loaded languages") + log.Println(b.Translations()) + } + return &I18nMiddleware{config: c} +} + +func (i *I18nMiddleware) Middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + bycookie := false + lang := r.URL.Query().Get(i.config.URLParam) + rlang := r.Header.Get("Accept-Language") + if lang == "" { + lc ,e := r.Cookie("lang") + if e != nil { + lang = "" + } else { + lang = lc.Value + bycookie = true + } + } + if !bycookie { + http.SetCookie(w, &http.Cookie{HttpOnly:true, Name: "lang", Value:lang}) + } + ctx0 := context.WithValue(r.Context(), "i18nlang", lang) + ctx1 := context.WithValue(ctx0, "i18nrlang", rlang) + ctx2 := context.WithValue(ctx1, "i18ndlang", i.config.DefaultLanguage) + ctx3 := context.WithValue(ctx2, "i18nTfunc", i.config.bundle.MustTfunc(lang, rlang, i.config.DefaultLanguage)) + next.ServeHTTP(w, r.WithContext(ctx3)) + }) +} \ No newline at end of file