github.com/mayra-cabrera/buffalo@v0.9.4-0.20170814145312-66d2e7772f11/middleware/i18n/i18n.go (about) 1 package i18n 2 3 import ( 4 "log" 5 6 "github.com/gobuffalo/buffalo" 7 "github.com/gobuffalo/packr" 8 "github.com/nicksnyder/go-i18n/i18n" 9 "github.com/nicksnyder/go-i18n/i18n/language" 10 "github.com/nicksnyder/go-i18n/i18n/translation" 11 "github.com/pkg/errors" 12 ) 13 14 // LanguageFinder can be implemented for custom finding of search 15 // languages. This can be useful if you want to load a user's langugage 16 // from something like a database. See Middleware() for more information 17 // on how the default implementation searches for languages. 18 type LanguageFinder func(*Translator, buffalo.Context) []string 19 20 // Translator for handling all your i18n needs. 21 type Translator struct { 22 // Box - where are the files? 23 Box packr.Box 24 // DefaultLanguage - default is "en-US" 25 DefaultLanguage string 26 // CookieName - name of the cookie to find the desired language. 27 // default is "lang" 28 CookieName string 29 // SessionName - name of the session to find the desired language. 30 // default is "lang" 31 SessionName string 32 // HelperName - name of the view helper. default is "t" 33 HelperName string 34 LanguageFinder LanguageFinder 35 } 36 37 // Load translations from the t.Box. 38 func (t *Translator) Load() error { 39 return t.Box.Walk(func(path string, f packr.File) error { 40 b, err := t.Box.MustBytes(path) 41 if err != nil { 42 log.Fatal(err) 43 return errors.WithStack(err) 44 } 45 return i18n.ParseTranslationFileBytes(path, b) 46 }) 47 } 48 49 // AddTranslation directly, without using a file. This is useful if you wish to load translations 50 // from a database, instead of disk. 51 func (t *Translator) AddTranslation(lang *language.Language, translations ...translation.Translation) { 52 i18n.AddTranslation(lang, translations...) 53 } 54 55 // New Translator. Requires a packr.Box that points to the location 56 // of the translation files, as well as a default language. This will 57 // also call t.Load() and load the translations from disk. 58 func New(box packr.Box, language string) (*Translator, error) { 59 t := &Translator{ 60 Box: box, 61 DefaultLanguage: language, 62 CookieName: "lang", 63 SessionName: "lang", 64 HelperName: "t", 65 LanguageFinder: defaultLanguageFinder, 66 } 67 return t, t.Load() 68 } 69 70 // Middleware for loading the translations for the language(s) 71 // selected. By default languages are loaded in the following order: 72 // 73 // Cookie - "lang" 74 // Header - "Accept-Language" 75 // Default - "en-US" 76 // 77 // These values can be changed on the Translator itself. In development 78 // model the translation files will be reloaded on each request. 79 func (t *Translator) Middleware() buffalo.MiddlewareFunc { 80 return func(next buffalo.Handler) buffalo.Handler { 81 return func(c buffalo.Context) error { 82 83 // in development reload the translations 84 if c.Value("env").(string) == "development" { 85 err := t.Load() 86 if err != nil { 87 return err 88 } 89 } 90 91 // set up the helper function for the views: 92 c.Set(t.HelperName, func(s string) (string, error) { 93 return t.Translate(c, s) 94 }) 95 return next(c) 96 } 97 } 98 } 99 100 // Translate a string given a Context 101 func (t *Translator) Translate(c buffalo.Context, s string) (string, error) { 102 if langs := c.Value("languages"); langs == nil { 103 c.Set("languages", t.LanguageFinder(t, c)) 104 } 105 langs := c.Value("languages").([]string) 106 T, err := i18n.Tfunc(langs[0], langs[1:]...) 107 if err != nil { 108 return "", err 109 } 110 return T(s, c.Data()), nil 111 } 112 113 func defaultLanguageFinder(t *Translator, c buffalo.Context) []string { 114 langs := []string{} 115 116 r := c.Request() 117 118 // try to get the language from a cookie: 119 if cookie, err := r.Cookie(t.CookieName); err == nil { 120 if cookie.Value != "" { 121 langs = append(langs, cookie.Value) 122 } 123 } 124 125 // try to get the language from the session 126 if s := c.Session().Get(t.SessionName); s != nil { 127 langs = append(langs, s.(string)) 128 } 129 130 // try to get the language from a header: 131 acceptLang := r.Header.Get("Accept-Language") 132 if acceptLang != "" { 133 langs = append(langs, acceptLang) 134 } 135 136 // try to get the language from the session: 137 langs = append(langs, t.DefaultLanguage) 138 return langs 139 }