You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
6.8KB

  1. /*
  2. Package gotext implements GNU gettext utilities.
  3. For quick/simple translations you can use the package level functions directly.
  4. import (
  5. "fmt"
  6. "github.com/leonelquinteros/gotext"
  7. )
  8. func main() {
  9. // Configure package
  10. gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")
  11. // Translate text from default domain
  12. fmt.Println(gotext.Get("My text on 'domain-name' domain"))
  13. // Translate text from a different domain without reconfigure
  14. fmt.Println(gotext.GetD("domain2", "Another text on a different domain"))
  15. }
  16. */
  17. package gotext
  18. import (
  19. "sync"
  20. )
  21. // Global environment variables
  22. type config struct {
  23. sync.RWMutex
  24. // Default domain to look at when no domain is specified. Used by package level functions.
  25. domain string
  26. // Language set.
  27. language string
  28. // Path to library directory where all locale directories and Translation files are.
  29. library string
  30. // Storage for package level methods
  31. storage *Locale
  32. }
  33. var globalConfig *config
  34. // Init default configuration
  35. func init() {
  36. globalConfig = &config{
  37. domain: "default",
  38. language: "en_US",
  39. library: "/usr/local/share/locale",
  40. storage: nil,
  41. }
  42. }
  43. // loadStorage creates a new Locale object at package level based on the Global variables settings.
  44. // It's called automatically when trying to use Get or GetD methods.
  45. func loadStorage(force bool) {
  46. globalConfig.Lock()
  47. if globalConfig.storage == nil || force {
  48. globalConfig.storage = NewLocale(globalConfig.library, globalConfig.language)
  49. }
  50. if _, ok := globalConfig.storage.Domains[globalConfig.domain]; !ok || force {
  51. globalConfig.storage.AddDomain(globalConfig.domain)
  52. }
  53. globalConfig.Unlock()
  54. }
  55. // GetDomain is the domain getter for the package configuration
  56. func GetDomain() string {
  57. var dom string
  58. globalConfig.RLock()
  59. if globalConfig.storage != nil {
  60. dom = globalConfig.storage.GetDomain()
  61. }
  62. if dom == "" {
  63. dom = globalConfig.domain
  64. }
  65. globalConfig.RUnlock()
  66. return dom
  67. }
  68. // SetDomain sets the name for the domain to be used at package level.
  69. // It reloads the corresponding Translation file.
  70. func SetDomain(dom string) {
  71. globalConfig.Lock()
  72. globalConfig.domain = dom
  73. if globalConfig.storage != nil {
  74. globalConfig.storage.SetDomain(dom)
  75. }
  76. globalConfig.Unlock()
  77. loadStorage(true)
  78. }
  79. // GetLanguage is the language getter for the package configuration
  80. func GetLanguage() string {
  81. globalConfig.RLock()
  82. lang := globalConfig.language
  83. globalConfig.RUnlock()
  84. return lang
  85. }
  86. // SetLanguage sets the language code to be used at package level.
  87. // It reloads the corresponding Translation file.
  88. func SetLanguage(lang string) {
  89. globalConfig.Lock()
  90. globalConfig.language = SimplifiedLocale(lang)
  91. globalConfig.Unlock()
  92. loadStorage(true)
  93. }
  94. // GetLibrary is the library getter for the package configuration
  95. func GetLibrary() string {
  96. globalConfig.RLock()
  97. lib := globalConfig.library
  98. globalConfig.RUnlock()
  99. return lib
  100. }
  101. // SetLibrary sets the root path for the loale directories and files to be used at package level.
  102. // It reloads the corresponding Translation file.
  103. func SetLibrary(lib string) {
  104. globalConfig.Lock()
  105. globalConfig.library = lib
  106. globalConfig.Unlock()
  107. loadStorage(true)
  108. }
  109. // Configure sets all configuration variables to be used at package level and reloads the corresponding Translation file.
  110. // It receives the library path, language code and domain name.
  111. // This function is recommended to be used when changing more than one setting,
  112. // as using each setter will introduce a I/O overhead because the Translation file will be loaded after each set.
  113. func Configure(lib, lang, dom string) {
  114. globalConfig.Lock()
  115. globalConfig.library = lib
  116. globalConfig.language = SimplifiedLocale(lang)
  117. globalConfig.domain = dom
  118. globalConfig.storage.SetDomain(dom)
  119. globalConfig.Unlock()
  120. loadStorage(true)
  121. }
  122. // Get uses the default domain globally set to return the corresponding Translation of a given string.
  123. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  124. func Get(str string, vars ...interface{}) string {
  125. return GetD(GetDomain(), str, vars...)
  126. }
  127. // GetN retrieves the (N)th plural form of Translation for the given string in the default domain.
  128. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  129. func GetN(str, plural string, n int, vars ...interface{}) string {
  130. return GetND(GetDomain(), str, plural, n, vars...)
  131. }
  132. // GetD returns the corresponding Translation in the given domain for a given string.
  133. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  134. func GetD(dom, str string, vars ...interface{}) string {
  135. return GetND(dom, str, str, 1, vars...)
  136. }
  137. // GetND retrieves the (N)th plural form of Translation in the given domain for a given string.
  138. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  139. func GetND(dom, str, plural string, n int, vars ...interface{}) string {
  140. // Try to load default package Locale storage
  141. loadStorage(false)
  142. // Return Translation
  143. globalConfig.RLock()
  144. tr := globalConfig.storage.GetND(dom, str, plural, n, vars...)
  145. globalConfig.RUnlock()
  146. return tr
  147. }
  148. // GetC uses the default domain globally set to return the corresponding Translation of the given string in the given context.
  149. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  150. func GetC(str, ctx string, vars ...interface{}) string {
  151. return GetDC(GetDomain(), str, ctx, vars...)
  152. }
  153. // GetNC retrieves the (N)th plural form of Translation for the given string in the given context in the default domain.
  154. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  155. func GetNC(str, plural string, n int, ctx string, vars ...interface{}) string {
  156. return GetNDC(GetDomain(), str, plural, n, ctx, vars...)
  157. }
  158. // GetDC returns the corresponding Translation in the given domain for the given string in the given context.
  159. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  160. func GetDC(dom, str, ctx string, vars ...interface{}) string {
  161. return GetNDC(dom, str, str, 1, ctx, vars...)
  162. }
  163. // GetNDC retrieves the (N)th plural form of Translation in the given domain for a given string.
  164. // Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
  165. func GetNDC(dom, str, plural string, n int, ctx string, vars ...interface{}) string {
  166. // Try to load default package Locale storage
  167. loadStorage(false)
  168. // Return Translation
  169. globalConfig.RLock()
  170. tr := globalConfig.storage.GetNDC(dom, str, plural, n, ctx, vars...)
  171. globalConfig.RUnlock()
  172. return tr
  173. }