i18n.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package i18n
  2. import (
  3. "context"
  4. _ "embed"
  5. "encoding/json"
  6. "fmt"
  7. "strings"
  8. "sync"
  9. "git.dmitriygnatenko.ru/dima/go-common/logger"
  10. "github.com/gofiber/fiber/v2"
  11. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/models"
  12. )
  13. //go:embed ru.json
  14. var ruJsonContent []byte
  15. //go:embed en.json
  16. var enJsonContent []byte
  17. const (
  18. langParam = "lang"
  19. ru = "ru"
  20. en = "en"
  21. )
  22. type Language string
  23. var (
  24. once sync.Once
  25. i18n *I18n
  26. )
  27. type I18n struct {
  28. translations map[Language]map[string]string
  29. languages map[Language]models.Language
  30. defaultLanguage Language
  31. }
  32. func Init(req []models.Language) error {
  33. var err error
  34. once.Do(func() {
  35. var defaultLanguage Language
  36. translations := make(map[Language]map[string]string)
  37. languages := make(map[Language]models.Language)
  38. for i := range req {
  39. if req[i].IsDefault {
  40. defaultLanguage = Language(strings.ToLower(req[i].URL))
  41. }
  42. url := strings.ToLower(req[i].URL)
  43. languages[Language(url)] = req[i]
  44. switch url {
  45. case ru:
  46. ruTranslations := make(map[string]string)
  47. err = json.Unmarshal(ruJsonContent, &ruTranslations)
  48. if err != nil {
  49. logger.Warn(context.Background(), err.Error())
  50. continue
  51. }
  52. translations[Language(url)] = ruTranslations
  53. case en:
  54. enTranslations := make(map[string]string)
  55. err = json.Unmarshal(enJsonContent, &enTranslations)
  56. if err != nil {
  57. logger.Warn(context.Background(), err.Error())
  58. continue
  59. }
  60. translations[Language(url)] = enTranslations
  61. }
  62. }
  63. i18n = &I18n{
  64. translations: translations,
  65. defaultLanguage: defaultLanguage,
  66. languages: languages,
  67. }
  68. })
  69. return err
  70. }
  71. func T(lang Language, key string, args ...any) string {
  72. if i18n == nil {
  73. logger.Error(context.Background(), "i18n not initialized")
  74. return ""
  75. }
  76. if i18n.translations[lang] == nil {
  77. logger.Warnf(context.Background(), "i18n: language %s not initialized", lang)
  78. return ""
  79. }
  80. var translated string
  81. if len(args) == 0 {
  82. translated = i18n.translations[lang][key]
  83. } else {
  84. translated = fmt.Sprintf(i18n.translations[lang][key], args...)
  85. }
  86. if len(translated) == 0 {
  87. logger.Warnf(
  88. context.Background(),
  89. "i18n: language %s translation %s is not found", lang, key,
  90. )
  91. }
  92. return translated
  93. }
  94. func DefaultLanguage() Language {
  95. if i18n == nil {
  96. logger.Error(context.Background(), "i18n not initialized")
  97. return ""
  98. }
  99. return i18n.defaultLanguage
  100. }
  101. func LanguageFromContext(c *fiber.Ctx) Language {
  102. language := c.Params(langParam)
  103. if len(language) > 0 {
  104. return Language(language)
  105. }
  106. return DefaultLanguage()
  107. }
  108. func LanguageID(lang Language) models.LanguageID {
  109. if i18n == nil {
  110. logger.Error(context.Background(), "i18n not initialized")
  111. return 0
  112. }
  113. if language, ok := i18n.languages[lang]; ok {
  114. return language.ID
  115. }
  116. logger.Errorf(
  117. context.Background(),
  118. "i18n: language ID for %s language is not found", lang,
  119. )
  120. return 0
  121. }
  122. func LanguageFromID(id models.LanguageID) Language {
  123. if i18n == nil {
  124. logger.Error(context.Background(), "i18n not initialized")
  125. return DefaultLanguage()
  126. }
  127. for lang, modelLang := range i18n.languages {
  128. if modelLang.ID == id {
  129. return lang
  130. }
  131. }
  132. return DefaultLanguage()
  133. }