i18ner.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package i18n
  2. import (
  3. "context"
  4. "errors"
  5. "log"
  6. "net/http"
  7. "github.com/nicksnyder/go-i18n/v2/i18n"
  8. "golang.org/x/text/language"
  9. "gopkg.in/yaml.v2"
  10. )
  11. var Bundle = &i18n.Bundle{
  12. DefaultLanguage: language.English,
  13. UnmarshalFuncs: map[string]i18n.UnmarshalFunc{
  14. "yaml": yaml.Unmarshal,
  15. },
  16. }
  17. const localizerKey = "localizer"
  18. /*
  19. WithLocalizer() is a higher-order function injecting into the request context a
  20. printer for the language best matching the Accept-Language header in the incoming
  21. request.
  22. The wrapped handler can use Localizer() to get a message printer instance
  23. configured for the best available language for the request.
  24. */
  25. func WithLocalizer(h http.Handler) http.Handler {
  26. h2 := func(w http.ResponseWriter, r *http.Request) {
  27. localizer := i18n.NewLocalizer(Bundle, r.Header.Get("Accept-Language"))
  28. c := context.WithValue(r.Context(), localizerKey, localizer)
  29. h.ServeHTTP(w, r.WithContext(c))
  30. }
  31. return http.HandlerFunc(h2)
  32. }
  33. /*
  34. Localizer() returns a message printer configured for the language best matching the
  35. Accept-Language in the request, or panic if the handler invoking it was not
  36. wrapped by a WithLocalizer() call.
  37. */
  38. func Localizer(r *http.Request) *i18n.Localizer {
  39. ip := r.Context().Value(localizerKey)
  40. p, ok := ip.(*i18n.Localizer)
  41. if !ok {
  42. log.Println(errors.New("trying to use i18n.Localizer in a handler not wrapped with i18.WithLocalizer"))
  43. // In that case, p will be nil, which is a valid localizer doing no localization.
  44. }
  45. return p
  46. }