ut.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package ut
  2. import (
  3. "errors"
  4. "strings"
  5. "sync"
  6. )
  7. var utrans *UniversalTranslator
  8. var once sync.Once
  9. type translators map[string]*Translator
  10. // UniversalTranslator holds all locale Translator instances
  11. type UniversalTranslator struct {
  12. translators translators
  13. translatorsLowercase translators
  14. fallback *Translator
  15. }
  16. // newUniversalTranslator creates a new UniversalTranslator instance.
  17. func newUniversalTranslator() *UniversalTranslator {
  18. return &UniversalTranslator{
  19. translators: make(translators),
  20. translatorsLowercase: make(translators),
  21. }
  22. }
  23. // SetFallback registers the fallback Translator instance when no matching Translator
  24. // can be found via a given locale
  25. func SetFallback(translator *Translator) {
  26. utrans.fallback = translator
  27. }
  28. // GetFallback return the universal translators fallback translation
  29. func GetFallback() *Translator {
  30. return utrans.fallback
  31. }
  32. // FindTranslator trys to find a Translator based on an array of locales
  33. // and returns the first one it can find, otherwise returns the
  34. // fallback translator; the lowercase bool specifies whether to lookup
  35. // the locale by proper or lowercase name, why because the http
  36. // Accept-Language header passed by some browsers has the locale lowercased
  37. // and others proper name so this just makes it easier to lowercase, pass in
  38. // the lowecased array and lookup by lowercase name.
  39. func FindTranslator(locales []string, lowercase bool) *Translator {
  40. if lowercase {
  41. for _, locale := range locales {
  42. if t, ok := utrans.translatorsLowercase[locale]; ok {
  43. return t
  44. }
  45. }
  46. } else {
  47. for _, locale := range locales {
  48. if t, ok := utrans.translators[locale]; ok {
  49. return t
  50. }
  51. }
  52. }
  53. return utrans.fallback
  54. }
  55. // GetTranslator returns the specified translator for the given locale,
  56. // or error if not found
  57. func GetTranslator(locale string) (*Translator, error) {
  58. if t, ok := utrans.translators[locale]; ok {
  59. return t, nil
  60. }
  61. return nil, errors.New("Translator with locale '" + locale + "' counld not be found.")
  62. }
  63. // RegisterLocale registers the a locale with ut
  64. // initializes singleton + sets initial fallback language
  65. func RegisterLocale(loc *Locale) {
  66. once.Do(func() {
  67. utrans = newUniversalTranslator()
  68. })
  69. if _, ok := utrans.translators[loc.Locale]; ok {
  70. return
  71. }
  72. t := newTranslator(loc)
  73. if utrans.fallback == nil {
  74. utrans.fallback = t
  75. }
  76. utrans.translators[loc.Locale] = t
  77. utrans.translatorsLowercase[strings.ToLower(loc.Locale)] = t
  78. // have do once initialize singleton ut instance.
  79. }