universal-translator.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package ut
  2. import (
  3. "strings"
  4. "github.com/go-playground/locales"
  5. )
  6. // UniversalTranslator holds all locale & translation data
  7. type UniversalTranslator struct {
  8. translators map[string]Translator
  9. fallback Translator
  10. }
  11. // New returns a new UniversalTranslator instance set with
  12. // the fallback locale and locales it should support
  13. func New(fallback locales.Translator, supportedLocales ...locales.Translator) *UniversalTranslator {
  14. t := &UniversalTranslator{
  15. translators: make(map[string]Translator),
  16. }
  17. for _, v := range supportedLocales {
  18. trans := newTranslator(v)
  19. t.translators[strings.ToLower(trans.Locale())] = newTranslator(trans)
  20. if fallback.Locale() == v.Locale() {
  21. t.fallback = trans
  22. }
  23. }
  24. if t.fallback == nil && fallback != nil {
  25. t.fallback = newTranslator(fallback)
  26. }
  27. return t
  28. }
  29. // FindTranslator trys to find a Translator based on an array of locales
  30. // and returns the first one it can find, otherwise returns the
  31. // fallback translator.
  32. func (t *UniversalTranslator) FindTranslator(locales ...string) (trans Translator) {
  33. var ok bool
  34. for _, locale := range locales {
  35. if trans, ok = t.translators[strings.ToLower(locale)]; ok {
  36. return
  37. }
  38. }
  39. return t.fallback
  40. }
  41. // GetTranslator returns the specified translator for the given locale,
  42. // or fallback if not found
  43. func (t *UniversalTranslator) GetTranslator(locale string) Translator {
  44. if t, ok := t.translators[strings.ToLower(locale)]; ok {
  45. return t
  46. }
  47. return t.fallback
  48. }
  49. // AddTranslator adds the supplied translator, if it already exists the override param
  50. // will be checked and if false an error will be returned, otherwise the translator will be
  51. // overridden; if the fallback matches the supplied translator it will be overridden as well
  52. // NOTE: this is normally only used when translator is embedded within a library
  53. func (t *UniversalTranslator) AddTranslator(translator locales.Translator, override bool) error {
  54. lc := strings.ToLower(translator.Locale())
  55. _, ok := t.translators[lc]
  56. if ok && !override {
  57. return &ErrExistingTranslator{locale: translator.Locale()}
  58. }
  59. trans := newTranslator(translator)
  60. if t.fallback.Locale() == translator.Locale() {
  61. // because it's optional to have a fallback, I don't impose that limitation
  62. // don't know why you wouldn't but...
  63. if !override {
  64. return &ErrExistingTranslator{locale: translator.Locale()}
  65. }
  66. t.fallback = trans
  67. }
  68. t.translators[lc] = trans
  69. return nil
  70. }