Skip to content

Commit

Permalink
Add singleton support for ease of use
Browse files Browse the repository at this point in the history
  • Loading branch information
MJacred committed Aug 28, 2024
1 parent 8f901db commit 1f66fa2
Show file tree
Hide file tree
Showing 3 changed files with 652 additions and 0 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,46 @@ localizer.Localize(&i18n.LocalizeConfig{
}) // Nick has 2 cats.
```


Use the singleton to ease usage.

```go
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.MustParseMessageFileBytes([]byte(`
HelloCookie = "Hello Cookie!"
[Cookies]
one = "I have {{.PluralCount}} cookie!"
other = "I have {{.PluralCount}} cookies!"
[CookiesX]
other = "I have {{.X}} cookies!"
[CookiesX2]
one = "I have {{.PluralCount}} {{.X}} cookie!"
other = "I have {{.PluralCount}} {{.X}} cookies!"
[CookiesABC]
other = "I have {{.A}} cookies in my {{.B}} back at {{.C}}!"
[CookiesABC2]
other = "I have {{.PluralCount}} {{.A}} cookies in my {{.B}} back at {{.C}}!"
`), "en.toml")

localizer := i18n.NewLocalizer(bundle, "en-US")
i18n.SetLocalizerInstance(localizer)
i18n.SetABCParams([]string{"A", "B", "C"})

i18n.Localize("HelloCookie") // "Hello Cookie!"
i18n.LocalizePlural("Cookies", 4) // "I have 4 cookies!"
i18n.LocalizeTemplateSingle("CookiesX", "X", "chocolate") // "I have chocolate cookies!"
i18n.LocalizeTemplateSingleWithPlural("CookiesX2", 4, "X", "chocolate") // "I have 4 chocolate cookies!"
i18n.LocalizeTemplateX("CookiesABC", "chocolate", "basket", "home") // "I have chocolate cookies in my basket back at home!"
i18n.LocalizeTemplateXPlural("CookiesABC2", 400, "chocolate", "basket", "home") // "I have 400 chocolate cookies in my basket back at home!"
```


## Command goi18n

[![Go Reference](https://pkg.go.dev/badge/github.com/nicksnyder/go-i18n/v2/goi18n.svg)](https://pkg.go.dev/github.com/nicksnyder/go-i18n/v2/goi18n)
Expand Down
196 changes: 196 additions & 0 deletions i18n/singleton.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package i18n

import (
"sync"
)

var (
localizerSingletonOnce sync.Once
localizerInstance *Localizer
localizerMutex = &sync.Mutex{}

notLocalized string

abcParams []string
)

func GetLocalizerInstance() *Localizer {
localizerSingletonOnce.Do(func() {
if localizerInstance == nil {
localizerInstance = new(Localizer)
}
})
return localizerInstance
}

// SetLocalizerInstance must be run before using `GetLocalizerInstance()` in a multi-threading manner.
func SetLocalizerInstance(l *Localizer) {
if localizerMutex != nil {
localizerMutex.Lock()
defer localizerMutex.Unlock()
}

localizerInstance = l
}

// SetUseNotLocalizedInfo is optional.
func SetUseNotLocalizedInfo(use bool) {
if use {
notLocalized = Localize("NotLocalized")
} else {
notLocalized = ""
}
}

func ResetSingletonContext() {
SetUseNotLocalizedInfo(false)
SetABCParams(nil)
}

// Localize loads localization for static text.
//
// Use only if you called SetLocalizerInstance().
func Localize(id string) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{MessageID: id})
if err != nil {
return notLocalized
}
return localization
}

// LocalizePlural loads localization for text with plural count.
//
// Use only if you called SetLocalizerInstance().
func LocalizePlural(id string, count int) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{
MessageID: id,
PluralCount: count,
})
if err != nil {
return notLocalized
}
return localization
}

// LocalizeTemplate loads localization using template.
//
// Use only if you called SetLocalizerInstance().
func LocalizeTemplate(id string, templateData map[string]any) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{
MessageID: id,
TemplateData: templateData,
})
if err != nil {
return notLocalized
}
return localization
}

// LocalizeTemplateSingle loads localization using template which has only one key-value pair.
//
// Use only if you called SetLocalizerInstance().
func LocalizeTemplateSingle(id, singleKey string, singleValue any) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{
MessageID: id,
TemplateData: map[string]any{singleKey: singleValue},
})
if err != nil {
return notLocalized
}
return localization
}

// LocalizeTemplateSingleWithPlural loads localization using template
// which has only one key-value pair for text with plural count.
//
// Use only if you called SetLocalizerInstance().
func LocalizeTemplateSingleWithPlural(id string, count int, key string, value any) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{
MessageID: id,
TemplateData: map[string]any{
key: value,
"PluralCount": count,
},
PluralCount: count,
})
if err != nil {
return notLocalized
}
return localization
}

// SetABCParams defines the default keys for TemplateData when using an x-func.
// Defining a non-empty slice unlocks the following funcs:
// - LocalizeTemplateX()
// - LocalizeTemplateXPlural()
//
// Use only if you called SetLocalizerInstance().
func SetABCParams(abc []string) {
abcParams = abc
}

func buildABCTemplateData(values []any) map[string]any {
if len(values) > len(abcParams) {
return nil
}

data := map[string]any{}
for i, val := range values {
data[abcParams[i]] = val
}
return data
}

// LocalizeTemplateX assigns the given values to the TemplateData keys
// as per the key definitions you set by calling SetABCParams().
//
// Use only if you called SetLocalizerInstance().
func LocalizeTemplateX(id string, values ...any) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{
MessageID: id,
TemplateData: buildABCTemplateData(values),
})
if err != nil {
return notLocalized
}
return localization
}

// LocalizeTemplateXPlural assigns the given values to the TemplateData keys
// as per the key definitions you set by calling SetABCParams() with plural count.
//
// Use only if you called SetLocalizerInstance().
func LocalizeTemplateXPlural(id string, count int, values ...any) string {
localizerMutex.Lock()
defer localizerMutex.Unlock()

data := buildABCTemplateData(values)
data["PluralCount"] = count

localization, err := GetLocalizerInstance().Localize(&LocalizeConfig{
MessageID: id,
TemplateData: data,
})
if err != nil {
return notLocalized
}
return localization
}
Loading

0 comments on commit 1f66fa2

Please sign in to comment.