universal_translator.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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())] = 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, found bool) {
  33. for _, locale := range locales {
  34. if trans, found = t.translators[strings.ToLower(locale)]; found {
  35. return
  36. }
  37. }
  38. return t.fallback, false
  39. }
  40. // GetTranslator returns the specified translator for the given locale,
  41. // or fallback if not found
  42. func (t *UniversalTranslator) GetTranslator(locale string) (trans Translator, found bool) {
  43. if trans, found = t.translators[strings.ToLower(locale)]; found {
  44. return
  45. }
  46. return t.fallback, false
  47. }
  48. // GetFallback returns the fallback locale
  49. func (t *UniversalTranslator) GetFallback() Translator {
  50. return t.fallback
  51. }
  52. // AddTranslator adds the supplied translator, if it already exists the override param
  53. // will be checked and if false an error will be returned, otherwise the translator will be
  54. // overridden; if the fallback matches the supplied translator it will be overridden as well
  55. // NOTE: this is normally only used when translator is embedded within a library
  56. func (t *UniversalTranslator) AddTranslator(translator locales.Translator, override bool) error {
  57. lc := strings.ToLower(translator.Locale())
  58. _, ok := t.translators[lc]
  59. if ok && !override {
  60. return &ErrExistingTranslator{locale: translator.Locale()}
  61. }
  62. trans := newTranslator(translator)
  63. if t.fallback.Locale() == translator.Locale() {
  64. // because it's optional to have a fallback, I don't impose that limitation
  65. // don't know why you wouldn't but...
  66. if !override {
  67. return &ErrExistingTranslator{locale: translator.Locale()}
  68. }
  69. t.fallback = trans
  70. }
  71. t.translators[lc] = trans
  72. return nil
  73. }
  74. // VerifyTranslations runs through all locales and identifies any issues
  75. // eg. missing plural rules for a locale
  76. func (t *UniversalTranslator) VerifyTranslations() (err error) {
  77. for _, trans := range t.translators {
  78. err = trans.VerifyTranslations()
  79. if err != nil {
  80. return
  81. }
  82. }
  83. return
  84. }