feat(i18n): support translation context lookup
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
00b512063a
commit
50c528ccf9
2 changed files with 82 additions and 5 deletions
57
service.go
57
service.go
|
|
@ -344,14 +344,13 @@ func (s *Service) resolveWithFallback(messageID string, data any) string {
|
|||
}
|
||||
|
||||
func (s *Service) tryResolve(lang, key string, data any) string {
|
||||
formality := s.getEffectiveFormality(data)
|
||||
if formality != FormalityNeutral {
|
||||
formalityKey := key + "._" + formality.String()
|
||||
if text := s.resolveMessage(lang, formalityKey, data); text != "" {
|
||||
context, formality := s.getEffectiveContextAndFormality(data)
|
||||
for _, lookupKey := range lookupVariants(key, context, formality) {
|
||||
if text := s.resolveMessage(lang, lookupKey, data); text != "" {
|
||||
return text
|
||||
}
|
||||
}
|
||||
return s.resolveMessage(lang, key, data)
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *Service) resolveMessage(lang, key string, data any) string {
|
||||
|
|
@ -374,6 +373,39 @@ func (s *Service) resolveMessage(lang, key string, data any) string {
|
|||
return text
|
||||
}
|
||||
|
||||
func (s *Service) getEffectiveContextAndFormality(data any) (string, Formality) {
|
||||
if ctx, ok := data.(*TranslationContext); ok && ctx != nil {
|
||||
formality := ctx.FormalityValue()
|
||||
if formality == FormalityNeutral {
|
||||
formality = s.formality
|
||||
}
|
||||
return ctx.ContextString(), formality
|
||||
}
|
||||
if m, ok := data.(map[string]any); ok {
|
||||
var context string
|
||||
if v, ok := m["Context"].(string); ok {
|
||||
context = core.Trim(v)
|
||||
}
|
||||
if v, ok := m["Formality"]; ok {
|
||||
switch f := v.(type) {
|
||||
case Formality:
|
||||
if f != FormalityNeutral {
|
||||
return context, f
|
||||
}
|
||||
case string:
|
||||
switch core.Lower(f) {
|
||||
case "formal":
|
||||
return context, FormalityFormal
|
||||
case "informal":
|
||||
return context, FormalityInformal
|
||||
}
|
||||
}
|
||||
}
|
||||
return context, s.formality
|
||||
}
|
||||
return "", s.getEffectiveFormality(data)
|
||||
}
|
||||
|
||||
func (s *Service) getEffectiveFormality(data any) Formality {
|
||||
if ctx, ok := data.(*TranslationContext); ok && ctx != nil {
|
||||
if ctx.Formality != FormalityNeutral {
|
||||
|
|
@ -403,6 +435,21 @@ func (s *Service) getEffectiveFormality(data any) Formality {
|
|||
return s.formality
|
||||
}
|
||||
|
||||
func lookupVariants(key, context string, formality Formality) []string {
|
||||
var variants []string
|
||||
if context != "" {
|
||||
if formality != FormalityNeutral {
|
||||
variants = append(variants, key+"._"+context+"._"+formality.String())
|
||||
}
|
||||
variants = append(variants, key+"._"+context)
|
||||
}
|
||||
if formality != FormalityNeutral {
|
||||
variants = append(variants, key+"._"+formality.String())
|
||||
}
|
||||
variants = append(variants, key)
|
||||
return variants
|
||||
}
|
||||
|
||||
func (s *Service) handleMissingKey(key string, args []any) string {
|
||||
switch s.mode {
|
||||
case ModeStrict:
|
||||
|
|
|
|||
|
|
@ -202,6 +202,36 @@ func TestServiceFormality(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServiceTranslationContext(t *testing.T) {
|
||||
svc, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New() failed: %v", err)
|
||||
}
|
||||
|
||||
svc.AddMessages("en", map[string]string{
|
||||
"direction.right._navigation": "right",
|
||||
"direction.right._navigation._formal": "right, sir",
|
||||
"direction.right._correctness": "correct",
|
||||
"direction.right._correctness._formal": "correct, sir",
|
||||
})
|
||||
|
||||
if got := svc.T("direction.right", C("navigation")); got != "right" {
|
||||
t.Errorf("T(direction.right, C(navigation)) = %q, want %q", got, "right")
|
||||
}
|
||||
|
||||
if got := svc.T("direction.right", C("navigation").Formal()); got != "right, sir" {
|
||||
t.Errorf("T(direction.right, C(navigation).Formal()) = %q, want %q", got, "right, sir")
|
||||
}
|
||||
|
||||
if got := svc.T("direction.right", C("correctness")); got != "correct" {
|
||||
t.Errorf("T(direction.right, C(correctness)) = %q, want %q", got, "correct")
|
||||
}
|
||||
|
||||
if got := svc.T("direction.right", C("correctness").Formal()); got != "correct, sir" {
|
||||
t.Errorf("T(direction.right, C(correctness).Formal()) = %q, want %q", got, "correct, sir")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceDirection(t *testing.T) {
|
||||
svc, err := New()
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue