Merge pull request #69 from m-horky/is-translated
Runtime translation detection
This commit is contained in:
commit
4829902c8b
10 changed files with 332 additions and 31 deletions
92
domain.go
92
domain.go
|
@ -35,9 +35,9 @@ type Domain struct {
|
|||
pluralforms plurals.Expression
|
||||
|
||||
// Storage
|
||||
translations map[string]*Translation
|
||||
contexts map[string]map[string]*Translation
|
||||
pluralTranslations map[string]*Translation
|
||||
translations map[string]*Translation
|
||||
contextTranslations map[string]map[string]*Translation
|
||||
pluralTranslations map[string]*Translation
|
||||
|
||||
// Sync Mutex
|
||||
trMutex sync.RWMutex
|
||||
|
@ -84,7 +84,7 @@ func NewDomain() *Domain {
|
|||
domain.Headers = make(HeaderMap)
|
||||
domain.headerComments = make([]string, 0)
|
||||
domain.translations = make(map[string]*Translation)
|
||||
domain.contexts = make(map[string]map[string]*Translation)
|
||||
domain.contextTranslations = make(map[string]map[string]*Translation)
|
||||
domain.pluralTranslations = make(map[string]*Translation)
|
||||
|
||||
return domain
|
||||
|
@ -183,14 +183,14 @@ func (do *Domain) DropStaleTranslations() {
|
|||
defer do.trMutex.Unlock()
|
||||
defer do.pluralMutex.Unlock()
|
||||
|
||||
for name, ctx := range do.contexts {
|
||||
for name, ctx := range do.contextTranslations {
|
||||
for id, trans := range ctx {
|
||||
if trans.IsStale() {
|
||||
delete(ctx, id)
|
||||
}
|
||||
}
|
||||
if len(ctx) == 0 {
|
||||
delete(do.contexts, name)
|
||||
delete(do.contextTranslations, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ func (do *Domain) SetC(id, ctx, str string) {
|
|||
defer do.trMutex.Unlock()
|
||||
defer do.pluralMutex.Unlock()
|
||||
|
||||
if context, ok := do.contexts[ctx]; ok {
|
||||
if context, ok := do.contextTranslations[ctx]; ok {
|
||||
if trans, hasTrans := context[id]; hasTrans {
|
||||
trans.Set(str)
|
||||
} else {
|
||||
|
@ -325,7 +325,7 @@ func (do *Domain) SetC(id, ctx, str string) {
|
|||
trans := NewTranslation()
|
||||
trans.ID = id
|
||||
trans.Set(str)
|
||||
do.contexts[ctx] = map[string]*Translation{
|
||||
do.contextTranslations[ctx] = map[string]*Translation{
|
||||
id: trans,
|
||||
}
|
||||
}
|
||||
|
@ -337,11 +337,11 @@ func (do *Domain) GetC(str, ctx string, vars ...interface{}) string {
|
|||
do.trMutex.RLock()
|
||||
defer do.trMutex.RUnlock()
|
||||
|
||||
if do.contexts != nil {
|
||||
if _, ok := do.contexts[ctx]; ok {
|
||||
if do.contexts[ctx] != nil {
|
||||
if _, ok := do.contexts[ctx][str]; ok {
|
||||
return Printf(do.contexts[ctx][str].Get(), vars...)
|
||||
if do.contextTranslations != nil {
|
||||
if _, ok := do.contextTranslations[ctx]; ok {
|
||||
if do.contextTranslations[ctx] != nil {
|
||||
if _, ok := do.contextTranslations[ctx][str]; ok {
|
||||
return Printf(do.contextTranslations[ctx][str].Get(), vars...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ func (do *Domain) SetNC(id, plural, ctx string, n int, str string) {
|
|||
defer do.trMutex.Unlock()
|
||||
defer do.pluralMutex.Unlock()
|
||||
|
||||
if context, ok := do.contexts[ctx]; ok {
|
||||
if context, ok := do.contextTranslations[ctx]; ok {
|
||||
if trans, hasTrans := context[id]; hasTrans {
|
||||
trans.SetN(pluralForm, str)
|
||||
} else {
|
||||
|
@ -374,7 +374,7 @@ func (do *Domain) SetNC(id, plural, ctx string, n int, str string) {
|
|||
trans := NewTranslation()
|
||||
trans.ID = id
|
||||
trans.SetN(pluralForm, str)
|
||||
do.contexts[ctx] = map[string]*Translation{
|
||||
do.contextTranslations[ctx] = map[string]*Translation{
|
||||
id: trans,
|
||||
}
|
||||
}
|
||||
|
@ -386,11 +386,11 @@ func (do *Domain) GetNC(str, plural string, n int, ctx string, vars ...interface
|
|||
do.trMutex.RLock()
|
||||
defer do.trMutex.RUnlock()
|
||||
|
||||
if do.contexts != nil {
|
||||
if _, ok := do.contexts[ctx]; ok {
|
||||
if do.contexts[ctx] != nil {
|
||||
if _, ok := do.contexts[ctx][str]; ok {
|
||||
return Printf(do.contexts[ctx][str].GetN(do.pluralForm(n)), vars...)
|
||||
if do.contextTranslations != nil {
|
||||
if _, ok := do.contextTranslations[ctx]; ok {
|
||||
if do.contextTranslations[ctx] != nil {
|
||||
if _, ok := do.contextTranslations[ctx][str]; ok {
|
||||
return Printf(do.contextTranslations[ctx][str].GetN(do.pluralForm(n)), vars...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,7 +402,51 @@ func (do *Domain) GetNC(str, plural string, n int, ctx string, vars ...interface
|
|||
return Printf(plural, vars...)
|
||||
}
|
||||
|
||||
//GetTranslations returns a copy of every translation in the domain. It does not support contexts.
|
||||
// IsTranslated reports whether a string is translated
|
||||
func (do *Domain) IsTranslated(str string) bool {
|
||||
return do.IsTranslatedN(str, 0)
|
||||
}
|
||||
|
||||
// IsTranslatedN reports whether a plural string is translated
|
||||
func (do *Domain) IsTranslatedN(str string, n int) bool {
|
||||
do.trMutex.RLock()
|
||||
defer do.trMutex.RUnlock()
|
||||
|
||||
if do.translations == nil {
|
||||
return false
|
||||
}
|
||||
tr, ok := do.translations[str]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return tr.IsTranslatedN(n)
|
||||
}
|
||||
|
||||
// IsTranslatedC reports whether a context string is translated
|
||||
func (do *Domain) IsTranslatedC(str, ctx string) bool {
|
||||
return do.IsTranslatedNC(str, 0, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedNC reports whether a plural context string is translated
|
||||
func (do *Domain) IsTranslatedNC(str string, n int, ctx string) bool {
|
||||
do.trMutex.RLock()
|
||||
defer do.trMutex.RUnlock()
|
||||
|
||||
if do.contextTranslations == nil {
|
||||
return false
|
||||
}
|
||||
translations, ok := do.contextTranslations[ctx]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
tr, ok := translations[str]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return tr.IsTranslatedN(n)
|
||||
}
|
||||
|
||||
// GetTranslations returns a copy of every translation in the domain. It does not support contexts.
|
||||
func (do *Domain) GetTranslations() map[string]*Translation {
|
||||
all := make(map[string]*Translation, len(do.translations))
|
||||
|
||||
|
@ -511,7 +555,7 @@ func (do *Domain) MarshalText() ([]byte, error) {
|
|||
|
||||
// Just as with headers, output translations in consistent order (to minimise diffs between round-trips), with (first) source reference taking priority, followed by context and finally ID
|
||||
references := make([]SourceReference, 0)
|
||||
for name, ctx := range do.contexts {
|
||||
for name, ctx := range do.contextTranslations {
|
||||
for id, trans := range ctx {
|
||||
if id == "" {
|
||||
continue
|
||||
|
@ -623,7 +667,7 @@ func (do *Domain) MarshalBinary() ([]byte, error) {
|
|||
obj.Nplurals = do.nplurals
|
||||
obj.Plural = do.plural
|
||||
obj.Translations = do.translations
|
||||
obj.Contexts = do.contexts
|
||||
obj.Contexts = do.contextTranslations
|
||||
|
||||
var buff bytes.Buffer
|
||||
encoder := gob.NewEncoder(&buff)
|
||||
|
@ -649,7 +693,7 @@ func (do *Domain) UnmarshalBinary(data []byte) error {
|
|||
do.nplurals = obj.Nplurals
|
||||
do.plural = obj.Plural
|
||||
do.translations = obj.Translations
|
||||
do.contexts = obj.Contexts
|
||||
do.contextTranslations = obj.Contexts
|
||||
|
||||
if expr, err := plurals.Compile(do.plural); err == nil {
|
||||
do.pluralforms = expr
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
const (
|
||||
enUSFixture = "fixtures/en_US/default.po"
|
||||
arFixture = "fixtures/ar/categories.po"
|
||||
)
|
||||
|
||||
//since both Po and Mo just pass-through to Domain for MarshalBinary and UnmarshalBinary, test it here
|
||||
|
@ -72,6 +73,58 @@ func TestDomain_GetTranslations(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDomain_IsTranslated(t *testing.T) {
|
||||
englishPo := NewPo()
|
||||
englishPo.ParseFile(enUSFixture)
|
||||
english := englishPo.GetDomain()
|
||||
|
||||
// singular and plural
|
||||
if english.IsTranslated("My Text") {
|
||||
t.Error("'My text' should be reported as translated.")
|
||||
}
|
||||
if english.IsTranslated("Another string") {
|
||||
t.Error("'Another string' should be reported as not translated.")
|
||||
}
|
||||
if !english.IsTranslatedN("Empty plural form singular", 0) {
|
||||
t.Error("'Empty plural form singular' should be reported as translated for n=0.")
|
||||
}
|
||||
if english.IsTranslatedN("Empty plural form singular", 1) {
|
||||
t.Error("'Empty plural form singular' should be reported as not translated for n=1.")
|
||||
}
|
||||
|
||||
arabicPo := NewPo()
|
||||
arabicPo.ParseFile(arFixture)
|
||||
arabic := arabicPo.GetDomain()
|
||||
|
||||
// multiple plurals
|
||||
if !arabic.IsTranslated("Load %d more document") {
|
||||
t.Error("Arabic singular should be reported as translated.")
|
||||
}
|
||||
if !arabic.IsTranslatedN("Load %d more document", 0) {
|
||||
t.Error("Arabic plural should be reported as translated for n=0.")
|
||||
}
|
||||
if !arabic.IsTranslatedN("Load %d more document", 1) {
|
||||
t.Error("Arabic plural should be reported as translated for n=1.")
|
||||
}
|
||||
if !arabic.IsTranslatedN("Load %d more document", 5) {
|
||||
t.Error("Arabic plural should be reported as translated for n=5.")
|
||||
}
|
||||
if arabic.IsTranslatedN("Load %d more document", 6) {
|
||||
t.Error("Arabic plural should be reported as not translated for n=6.")
|
||||
}
|
||||
|
||||
// context
|
||||
if !english.IsTranslatedC("One with var: %s", "Ctx") {
|
||||
t.Error("Context singular should be reported as translated.")
|
||||
}
|
||||
if !english.IsTranslatedNC("One with var: %s", 0, "Ctx") {
|
||||
t.Error("Context plural should be reported as translated for n=0")
|
||||
}
|
||||
if english.IsTranslatedNC("One with var: %s", 2, "Ctx") {
|
||||
t.Error("Context plural should be reported as translated for n=2")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomain_CheckExportFormatting(t *testing.T) {
|
||||
po := NewPo()
|
||||
po.Set("myid", "test string\nwith \"newline\"")
|
||||
|
|
54
gotext.go
54
gotext.go
|
@ -245,3 +245,57 @@ func GetNDC(dom, str, plural string, n int, ctx string, vars ...interface{}) str
|
|||
|
||||
return tr
|
||||
}
|
||||
|
||||
// IsTranslated reports whether a string is translated
|
||||
func IsTranslated(str string) bool {
|
||||
return IsTranslatedND(GetDomain(), str, 0)
|
||||
}
|
||||
|
||||
// IsTranslatedN reports whether a plural string is translated
|
||||
func IsTranslatedN(str string, n int) bool {
|
||||
return IsTranslatedND(GetDomain(), str, n)
|
||||
}
|
||||
|
||||
// IsTranslatedD reports whether a domain string is translated
|
||||
func IsTranslatedD(dom, str string) bool {
|
||||
return IsTranslatedND(dom, str, 0)
|
||||
}
|
||||
|
||||
// IsTranslatedND reports whether a plural domain string is translated
|
||||
func IsTranslatedND(dom, str string, n int) bool {
|
||||
loadStorage(false)
|
||||
|
||||
globalConfig.RLock()
|
||||
defer globalConfig.RUnlock()
|
||||
|
||||
if _, ok := globalConfig.storage.Domains[dom]; !ok {
|
||||
globalConfig.storage.AddDomain(dom)
|
||||
}
|
||||
|
||||
return globalConfig.storage.IsTranslatedND(dom, str, n)
|
||||
}
|
||||
|
||||
// IsTranslatedC reports whether a context string is translated
|
||||
func IsTranslatedC(str, ctx string) bool {
|
||||
return IsTranslatedNDC(GetDomain(), str, 0, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedNC reports whether a plural context string is translated
|
||||
func IsTranslatedNC(str string, n int, ctx string) bool {
|
||||
return IsTranslatedNDC(GetDomain(), str, n, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedDC reports whether a domain context string is translated
|
||||
func IsTranslatedDC(dom, str, ctx string) bool {
|
||||
return IsTranslatedNDC(dom, str, 0, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedNDC reports whether a plural domain context string is translated
|
||||
func IsTranslatedNDC(dom, str string, n int, ctx string) bool {
|
||||
loadStorage(false)
|
||||
|
||||
globalConfig.RLock()
|
||||
defer globalConfig.RUnlock()
|
||||
|
||||
return globalConfig.storage.IsTranslatedNDC(dom, str, n, ctx)
|
||||
}
|
||||
|
|
|
@ -176,6 +176,33 @@ msgstr "Another text on another domain"
|
|||
if tr != "Another text on another domain" {
|
||||
t.Errorf("Expected 'Another text on another domain' but got '%s'", tr)
|
||||
}
|
||||
|
||||
// Test IsTranslation functions
|
||||
if !IsTranslated("My text") {
|
||||
t.Error("'My text' should be reported as translated.")
|
||||
}
|
||||
if IsTranslated("Another string") {
|
||||
t.Error("'Another string' should be reported as not translated.")
|
||||
}
|
||||
plural := "One with var: %s"
|
||||
if !IsTranslated(plural) {
|
||||
t.Errorf("'%s' should be reported as translated for singular.", plural)
|
||||
}
|
||||
if !IsTranslatedN(plural, 0) {
|
||||
t.Errorf("'%s' should be reported as translated for n=0.", plural)
|
||||
}
|
||||
if !IsTranslatedN(plural, 2) {
|
||||
t.Errorf("'%s' should be reported as translated for n=2.", plural)
|
||||
}
|
||||
if !IsTranslatedC("Some random in a context", "Ctx") {
|
||||
t.Errorf("'Some random in a context' should be reported as translated under context.")
|
||||
}
|
||||
if !IsTranslatedC(plural, "Ctx") {
|
||||
t.Errorf("'%s' should be reported as translated for singular under context.", plural)
|
||||
}
|
||||
if !IsTranslatedNC(plural, 0, "Ctx") {
|
||||
t.Errorf("'%s' should be reported as translated for n=0 under context.", plural)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUntranslated(t *testing.T) {
|
||||
|
|
25
introspector.go
Normal file
25
introspector.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package gotext
|
||||
|
||||
// IsTranslatedIntrospector is able to determine whether a given string is translated.
|
||||
// Examples of this introspector are Po and Mo, which are specific to their domain.
|
||||
// Locale holds multiple domains and also implements IsTranslatedDomainIntrospector.
|
||||
type IsTranslatedIntrospector interface {
|
||||
IsTranslated(str string) bool
|
||||
IsTranslatedN(str string, n int) bool
|
||||
IsTranslatedC(str, ctx string) bool
|
||||
IsTranslatedNC(str string, n int, ctx string) bool
|
||||
}
|
||||
|
||||
// IsTranslatedDomainIntrospector is able to determine whether a given string is translated.
|
||||
// Example of this introspector is Locale, which holds multiple domains.
|
||||
// Simpler objects that are domain-specific, like Po or Mo, implement IsTranslatedIntrospector.
|
||||
type IsTranslatedDomainIntrospector interface {
|
||||
IsTranslated(str string) bool
|
||||
IsTranslatedN(str string, n int) bool
|
||||
IsTranslatedD(dom, str string) bool
|
||||
IsTranslatedND(dom, str string, n int) bool
|
||||
IsTranslatedC(str, ctx string) bool
|
||||
IsTranslatedNC(str string, n int, ctx string) bool
|
||||
IsTranslatedDC(dom, str, ctx string) bool
|
||||
IsTranslatedNDC(dom, str string, n int, ctx string) bool
|
||||
}
|
60
locale.go
60
locale.go
|
@ -311,6 +311,66 @@ func (l *Locale) GetTranslations() map[string]*Translation {
|
|||
return all
|
||||
}
|
||||
|
||||
// IsTranslated reports whether a string is translated
|
||||
func (l *Locale) IsTranslated(str string) bool {
|
||||
return l.IsTranslatedND(l.GetDomain(), str, 0)
|
||||
}
|
||||
|
||||
// IsTranslatedN reports whether a plural string is translated
|
||||
func (l *Locale) IsTranslatedN(str string, n int) bool {
|
||||
return l.IsTranslatedND(l.GetDomain(), str, n)
|
||||
}
|
||||
|
||||
// IsTranslatedD reports whether a domain string is translated
|
||||
func (l *Locale) IsTranslatedD(dom, str string) bool {
|
||||
return l.IsTranslatedND(dom, str, 0)
|
||||
}
|
||||
|
||||
// IsTranslatedND reports whether a plural domain string is translated
|
||||
func (l *Locale) IsTranslatedND(dom, str string, n int) bool {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
|
||||
if l.Domains == nil {
|
||||
return false
|
||||
}
|
||||
translator, ok := l.Domains[dom]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return translator.GetDomain().IsTranslatedN(str, n)
|
||||
}
|
||||
|
||||
// IsTranslatedC reports whether a context string is translated
|
||||
func (l *Locale) IsTranslatedC(str, ctx string) bool {
|
||||
return l.IsTranslatedNDC(l.GetDomain(), str, 0, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedNC reports whether a plural context string is translated
|
||||
func (l *Locale) IsTranslatedNC(str string, n int, ctx string) bool {
|
||||
return l.IsTranslatedNDC(l.GetDomain(), str, n, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedDC reports whether a domain context string is translated
|
||||
func (l *Locale) IsTranslatedDC(dom, str, ctx string) bool {
|
||||
return l.IsTranslatedNDC(dom, str, 0, ctx)
|
||||
}
|
||||
|
||||
// IsTranslatedNDC reports whether a plural domain context string is translated
|
||||
func (l *Locale) IsTranslatedNDC(dom string, str string, n int, ctx string) bool {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
|
||||
if l.Domains == nil {
|
||||
return false
|
||||
}
|
||||
translator, ok := l.Domains[dom]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return translator.GetDomain().IsTranslatedNC(str, n, ctx)
|
||||
}
|
||||
|
||||
// LocaleEncoding is used as intermediary storage to encode Locale objects to Gob.
|
||||
type LocaleEncoding struct {
|
||||
Path string
|
||||
|
|
19
mo.go
19
mo.go
|
@ -92,6 +92,19 @@ func (mo *Mo) GetNC(str, plural string, n int, ctx string, vars ...interface{})
|
|||
return mo.domain.GetNC(str, plural, n, ctx, vars...)
|
||||
}
|
||||
|
||||
func (mo *Mo) IsTranslated(str string) bool {
|
||||
return mo.domain.IsTranslated(str)
|
||||
}
|
||||
func (mo *Mo) IsTranslatedN(str string, n int) bool {
|
||||
return mo.domain.IsTranslatedN(str, n)
|
||||
}
|
||||
func (mo *Mo) IsTranslatedC(str, ctx string) bool {
|
||||
return mo.domain.IsTranslatedC(str, ctx)
|
||||
}
|
||||
func (mo *Mo) IsTranslatedNC(str string, n int, ctx string) bool {
|
||||
return mo.domain.IsTranslatedNC(str, n, ctx)
|
||||
}
|
||||
|
||||
func (mo *Mo) MarshalBinary() ([]byte, error) {
|
||||
return mo.domain.MarshalBinary()
|
||||
}
|
||||
|
@ -263,10 +276,10 @@ func (mo *Mo) addTranslation(msgid, msgstr []byte) {
|
|||
|
||||
if len(msgctxt) > 0 {
|
||||
// With context...
|
||||
if _, ok := mo.domain.contexts[string(msgctxt)]; !ok {
|
||||
mo.domain.contexts[string(msgctxt)] = make(map[string]*Translation)
|
||||
if _, ok := mo.domain.contextTranslations[string(msgctxt)]; !ok {
|
||||
mo.domain.contextTranslations[string(msgctxt)] = make(map[string]*Translation)
|
||||
}
|
||||
mo.domain.contexts[string(msgctxt)][translation.ID] = translation
|
||||
mo.domain.contextTranslations[string(msgctxt)][translation.ID] = translation
|
||||
} else {
|
||||
mo.domain.translations[translation.ID] = translation
|
||||
}
|
||||
|
|
19
po.go
19
po.go
|
@ -114,6 +114,19 @@ func (po *Po) GetNC(str, plural string, n int, ctx string, vars ...interface{})
|
|||
return po.domain.GetNC(str, plural, n, ctx, vars...)
|
||||
}
|
||||
|
||||
func (po *Po) IsTranslated(str string) bool {
|
||||
return po.domain.IsTranslated(str)
|
||||
}
|
||||
func (po *Po) IsTranslatedN(str string, n int) bool {
|
||||
return po.domain.IsTranslatedN(str, n)
|
||||
}
|
||||
func (po *Po) IsTranslatedC(str, ctx string) bool {
|
||||
return po.domain.IsTranslatedC(str, ctx)
|
||||
}
|
||||
func (po *Po) IsTranslatedNC(str string, n int, ctx string) bool {
|
||||
return po.domain.IsTranslatedNC(str, n, ctx)
|
||||
}
|
||||
|
||||
func (po *Po) MarshalText() ([]byte, error) {
|
||||
return po.domain.MarshalText()
|
||||
}
|
||||
|
@ -223,10 +236,10 @@ func (po *Po) saveBuffer() {
|
|||
po.domain.translations[po.domain.trBuffer.ID] = po.domain.trBuffer
|
||||
} else {
|
||||
// With context...
|
||||
if _, ok := po.domain.contexts[po.domain.ctxBuffer]; !ok {
|
||||
po.domain.contexts[po.domain.ctxBuffer] = make(map[string]*Translation)
|
||||
if _, ok := po.domain.contextTranslations[po.domain.ctxBuffer]; !ok {
|
||||
po.domain.contextTranslations[po.domain.ctxBuffer] = make(map[string]*Translation)
|
||||
}
|
||||
po.domain.contexts[po.domain.ctxBuffer][po.domain.trBuffer.ID] = po.domain.trBuffer
|
||||
po.domain.contextTranslations[po.domain.ctxBuffer][po.domain.trBuffer.ID] = po.domain.trBuffer
|
||||
|
||||
// Cleanup current context buffer if needed
|
||||
if po.domain.trBuffer.ID != "" {
|
||||
|
|
|
@ -78,3 +78,15 @@ func (t *Translation) GetN(n int) string {
|
|||
// Return untranslated plural by default
|
||||
return t.PluralID
|
||||
}
|
||||
|
||||
// IsTranslated reports whether a string is translated
|
||||
func (t *Translation) IsTranslated() bool {
|
||||
tr, ok := t.Trs[0]
|
||||
return tr != "" && ok
|
||||
}
|
||||
|
||||
// IsTranslatedN reports whether a plural string is translated
|
||||
func (t *Translation) IsTranslatedN(n int) bool {
|
||||
tr, ok := t.Trs[n]
|
||||
return tr != "" && ok
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ func (te *TranslatorEncoding) GetTranslator() Translator {
|
|||
po.domain.nplurals = te.Nplurals
|
||||
po.domain.plural = te.Plural
|
||||
po.domain.translations = te.Translations
|
||||
po.domain.contexts = te.Contexts
|
||||
po.domain.contextTranslations = te.Contexts
|
||||
|
||||
return po
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue