Browse Source

Add variants of Get functions with existence checks

Currently, a translation that doesn't exist just defaults to the
passed message ID.

It can be helpful to be able to catch these missing cases e.g. to
save to a log.

This PR implements variants ending in 'E' like GetE, GetNE.

This wasn't implemented at the package-level scope, because for
quick translations like that the extra flexibility probably isn't
needed.
tags/v1.4.1
Ben Sarah Golightly 1 year ago
parent
commit
75a1fb9b04
6 changed files with 326 additions and 4 deletions
  1. +105
    -0
      locale.go
  2. +84
    -0
      mo.go
  3. +85
    -0
      po.go
  4. +20
    -4
      po_test.go
  5. +26
    -0
      translation.go
  6. +6
    -0
      translator.go

+ 105
- 0
locale.go View File

@@ -271,6 +271,111 @@ func (l *Locale) GetNDC(dom, str, plural string, n int, ctx string, vars ...inte
return Printf(plural, vars...)
}

// Get Euses a domain "default" to return the corresponding Translation of a given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetE(str string, vars ...interface{}) (string, bool) {
return l.GetDE(l.GetDomain(), str, vars...)
}

// GetNE retrieves the (N)th plural form of Translation for the given string in the "default" domain.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetNE(str, plural string, n int, vars ...interface{}) (string, bool) {
return l.GetNDE(l.GetDomain(), str, plural, n, vars...)
}

// GetDE returns the corresponding Translation in the given domain for the given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetDE(dom, str string, vars ...interface{}) (string, bool) {
// Sync read
l.RLock()
defer l.RUnlock()

if l.Domains != nil {
if _, ok := l.Domains[dom]; ok {
if l.Domains[dom] != nil {
return l.Domains[dom].GetE(str, vars...)
}
}
}

return "", false
}

// GetNDE retrieves the (N)th plural form of Translation in the given domain for the given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetNDE(dom, str, plural string, n int, vars ...interface{}) (string, bool) {
// Sync read
l.RLock()
defer l.RUnlock()

if l.Domains != nil {
if _, ok := l.Domains[dom]; ok {
if l.Domains[dom] != nil {
return l.Domains[dom].GetNE(str, plural, n, vars...)
}
}
}

// Use western default rule (plural > 1) to handle missing domain default result.
return "", false
}

// GetC uses a domain "default" to return the corresponding Translation of the given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetCE(str, ctx string, vars ...interface{}) (string, bool) {
return l.GetDCE(l.GetDomain(), str, ctx, vars...)
}

// GetNC retrieves the (N)th plural form of Translation for the given string in the given context in the "default" domain.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetNCE(str, plural string, n int, ctx string, vars ...interface{}) (string, bool) {
return l.GetNDCE(l.GetDomain(), str, plural, n, ctx, vars...)
}

// GetDCE returns the corresponding Translation in the given domain for the given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
func (l *Locale) GetDCE(dom, str, ctx string, vars ...interface{}) (string, bool) {
// Sync read
l.RLock()
defer l.RUnlock()

if l.Domains != nil {
if _, ok := l.Domains[dom]; ok {
if l.Domains[dom] != nil {
return l.Domains[dom].GetCE(str, ctx, vars...)
}
}
}

return "", false
}

// GetNDCE retrieves the (N)th plural form of Translation in the given domain for the given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (l *Locale) GetNDCE(dom, str, plural string, n int, ctx string, vars ...interface{}) (string, bool) {
// Sync read
l.RLock()
defer l.RUnlock()

if l.Domains != nil {
if _, ok := l.Domains[dom]; ok {
if l.Domains[dom] != nil {
return l.Domains[dom].GetNCE(str, plural, n, ctx, vars...)
}
}
}

// Use western default rule (plural > 1) to handle missing domain default result.
return "", false
}

// LocaleEncoding is used as intermediary storage to encode Locale objects to Gob.
type LocaleEncoding struct {
Path string


+ 84
- 0
mo.go View File

@@ -427,6 +427,90 @@ func (mo *Mo) GetNC(str, plural string, n int, ctx string, vars ...interface{})
return Printf(plural, vars...)
}

// GetE retrieves the corresponding Translation for the given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (mo *Mo) GetE(str string, vars ...interface{}) (string, bool) {
// Sync read
mo.RLock()
defer mo.RUnlock()

if mo.translations != nil {
if _, ok := mo.translations[str]; ok {
if fmt, ok := mo.translations[str].GetE(); ok {
return Printf(fmt, vars...), true
}
}
}

return "", false
}

// GetNE retrieves the (N)th plural form of Translation for the given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (mo *Mo) GetNE(str, plural string, n int, vars ...interface{}) (string, bool) {
// Sync read
mo.RLock()
defer mo.RUnlock()

if mo.translations != nil {
if _, ok := mo.translations[str]; ok {
if fmt, ok := mo.translations[str].GetNE(mo.pluralForm(n)); ok {
return Printf(fmt, vars...), true
}
}
}

return "", false
}

// GetCE retrieves the corresponding Translation for a given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (mo *Mo) GetCE(str, ctx string, vars ...interface{}) (string, bool) {
// Sync read
mo.RLock()
defer mo.RUnlock()

if mo.contexts != nil {
if _, ok := mo.contexts[ctx]; ok {
if mo.contexts[ctx] != nil {
if _, ok := mo.contexts[ctx][str]; ok {
if fmt, ok := mo.contexts[ctx][str].GetE(); ok {
return Printf(fmt, vars...), true
}
}
}
}
}

return "", false
}

// GetNCE retrieves the (N)th plural form of Translation for the given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (mo *Mo) GetNCE(str, plural string, n int, ctx string, vars ...interface{}) (string, bool) {
// Sync read
mo.RLock()
defer mo.RUnlock()

if mo.contexts != nil {
if _, ok := mo.contexts[ctx]; ok {
if mo.contexts[ctx] != nil {
if _, ok := mo.contexts[ctx][str]; ok {
if fmt, ok := mo.contexts[ctx][str].GetNE(mo.pluralForm(n)); ok {
return Printf(fmt, vars...), true
}
}
}
}
}

return "", false
}

// MarshalBinary implements encoding.BinaryMarshaler interface
func (mo *Mo) MarshalBinary() ([]byte, error) {
obj := new(TranslatorEncoding)


+ 85
- 0
po.go View File

@@ -456,6 +456,91 @@ func (po *Po) GetNC(str, plural string, n int, ctx string, vars ...interface{})
return Printf(plural, vars...)
}

// Get Eretrieves the corresponding Translation for the given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (po *Po) GetE(str string, vars ...interface{}) (string, bool) {
// Sync read
po.RLock()
defer po.RUnlock()

if po.translations != nil {
if _, ok := po.translations[str]; ok {
if fmt, ok := po.translations[str].GetE(); ok {
return Printf(fmt, vars...), true
}
}
}

return "", false
}

// GetN Eretrieves the (N)th plural form of Translation for the given string.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (po *Po) GetNE(str, plural string, n int, vars ...interface{}) (string, bool) {
// Sync read
po.RLock()
defer po.RUnlock()

if po.translations != nil {
if _, ok := po.translations[str]; ok {
if fmt, ok := po.translations[str].GetNE(po.pluralForm(n)); ok {
return Printf(fmt, vars...), true
}
}
}

return "", false
}

// GetCE retrieves the corresponding Translation for a given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (po *Po) GetCE(str, ctx string, vars ...interface{}) (string, bool) {
// Sync read
po.RLock()
defer po.RUnlock()

if po.contexts != nil {
if _, ok := po.contexts[ctx]; ok {
if po.contexts[ctx] != nil {
if _, ok := po.contexts[ctx][str]; ok {
if fmt, ok := po.contexts[ctx][str].GetE(); ok {
return Printf(fmt, vars...), true
}
}
}
}
}

return "", false
}

// GetNCE retrieves the (N)th plural form of Translation for the given string in the given context.
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
// The second return value is true iff the string was found.
func (po *Po) GetNCE(str, plural string, n int, ctx string, vars ...interface{}) (string, bool) {
// Sync read
po.RLock()
defer po.RUnlock()

if po.contexts != nil {
if _, ok := po.contexts[ctx]; ok {
if po.contexts[ctx] != nil {
if _, ok := po.contexts[ctx][str]; ok {
if fmt, ok := po.contexts[ctx][str].GetNE(po.pluralForm(n)); ok {
return Printf(fmt, vars...), true
}
}
}
}
}

// Parse plural forms to distinguish between plural and singular
return "", false
}

// MarshalBinary implements encoding.BinaryMarshaler interface
func (po *Po) MarshalBinary() ([]byte, error) {
obj := new(TranslatorEncoding)


+ 20
- 4
po_test.go View File

@@ -62,7 +62,7 @@ msgid ""
msgstr "id with multiline content"

# Multi-line msgid_plural
msgid ""
msgid ""
"multi"
"line"
"plural"
@@ -71,7 +71,7 @@ msgstr "plural id with multiline content"

#Multi-line string
msgid "Multi-line"
msgstr ""
msgstr ""
"Multi "
"line"

@@ -177,6 +177,22 @@ msgstr "More Translation"
t.Errorf("Expected 'This are tests' but got '%s'", tr)
}

// Test translations with existence check
tr, exists := po.GetE("My text")
if (tr != "Translated text") || (!exists) {
t.Errorf("Expected 'Translated text', true but got '%s', %v", tr, exists)
}
tr, exists = po.GetE("I don't exist")
if exists {
t.Errorf("Expected 'I don't exist' not to exist but got '%s'", tr)
}

tr = po.GetN("I don't exist", "We don't exist", 100)
if exists {
t.Errorf("Expected 'I/We don't exist' not to exist but got '%s'", tr)
}
// Test context translations
v = "Test"
tr = po.GetC("One with var: %s", "Ctx", v)
@@ -241,7 +257,7 @@ msgstr[0] "TR Singular: %s"
msgstr[1] "TR Plural: %s"
msgstr[2] "TR Plural 2: %s"

`
// Create po object
po := new(Po)
@@ -271,7 +287,7 @@ msgstr[0] "TR Singular: %s"
msgstr[1] "TR Plural: %s"
msgstr[2] "TR Plural 2: %s"

`
// Create po object
po := new(Po)


+ 26
- 0
translation.go View File

@@ -50,3 +50,29 @@ func (t *Translation) GetN(n int) string {
// Return untranslated plural by default
return t.PluralID
}

// Get returns the string of the translation. The second return value is true
// iff the string was found.
func (t *Translation) GetE() (string, bool) {
// Look for Translation index 0
if _, ok := t.Trs[0]; ok {
if t.Trs[0] != "" {
return t.Trs[0], true
}
}

return "", false
}

// GetN returns the string of the plural translation. The second return value
// is true iff the string was found.
func (t *Translation) GetNE(n int) (string, bool) {
// Look for Translation index
if _, ok := t.Trs[n]; ok {
if t.Trs[n] != "" {
return t.Trs[n], true
}
}

return "", false
}

+ 6
- 0
translator.go View File

@@ -13,11 +13,17 @@ import "net/textproto"
type Translator interface {
ParseFile(f string)
Parse(buf []byte)

Get(str string, vars ...interface{}) string
GetN(str, plural string, n int, vars ...interface{}) string
GetC(str, ctx string, vars ...interface{}) string
GetNC(str, plural string, n int, ctx string, vars ...interface{}) string

GetE(str string, vars ...interface{}) (string, bool)
GetNE(str, plural string, n int, vars ...interface{}) (string, bool)
GetCE(str, ctx string, vars ...interface{}) (string, bool)
GetNCE(str, plural string, n int, ctx string, vars ...interface{}) (string, bool)

MarshalBinary() ([]byte, error)
UnmarshalBinary([]byte) error
}


Loading…
Cancel
Save