From e9d39cdcb384f083962042c224273d129e32fcc6 Mon Sep 17 00:00:00 2001 From: jkoberg Date: Mon, 25 Mar 2024 13:14:01 +0100 Subject: [PATCH] move translation logic from notifications to own package Signed-off-by: jkoberg --- ocis-pkg/l10n/l10n.go | 51 +++++++++++++++++++ services/notifications/pkg/email/composer.go | 29 +++++++---- .../notifications/pkg/email/l10n/locate.go | 51 ------------------- 3 files changed, 69 insertions(+), 62 deletions(-) create mode 100644 ocis-pkg/l10n/l10n.go delete mode 100644 services/notifications/pkg/email/l10n/locate.go diff --git a/ocis-pkg/l10n/l10n.go b/ocis-pkg/l10n/l10n.go new file mode 100644 index 0000000000..658f60fd09 --- /dev/null +++ b/ocis-pkg/l10n/l10n.go @@ -0,0 +1,51 @@ +// package l10n holds translation mechanics that are used by user facing services (notifications, userlog, graph) +package l10n + +import ( + "io/fs" + "os" + + "github.com/leonelquinteros/gotext" +) + +// Translator is able to translate strings +type Translator struct { + fs fs.FS + defaultLocale string + domain string +} + +// NewTranslator creates a Translator with library path and language code and load default domain +func NewTranslator(defaultLocale string, domain string, fsys fs.FS) Translator { + return Translator{ + fs: fsys, + defaultLocale: defaultLocale, + domain: domain, + } +} + +// NewTranslatorFromCommonConfig creates a new Translator from legacy config +func NewTranslatorFromCommonConfig(defaultLocale string, domain string, path string, fsys fs.FS, fsSubPath string) Translator { + var filesystem fs.FS + if path == "" { + filesystem, _ = fs.Sub(fsys, fsSubPath) + } else { // use custom path instead + filesystem = os.DirFS(path) + } + return NewTranslator(defaultLocale, domain, filesystem) +} + +// Translate translates a string to the locale +func (t Translator) Translate(str, locale string) string { + return t.Locale(locale).Get(str) +} + +// Locale returns the gotext.Locale, use `.Get` method to translate strings +func (t Translator) Locale(locale string) *gotext.Locale { + l := gotext.NewLocaleFS(locale, t.fs) + if locale != "en" && len(l.GetTranslations()) == 0 { + l = gotext.NewLocaleFS(t.defaultLocale, t.fs) + } + l.AddDomain(t.domain) // make domain configurable only if needed + return l +} diff --git a/services/notifications/pkg/email/composer.go b/services/notifications/pkg/email/composer.go index 81f4cab1ac..b3f33f0bbb 100644 --- a/services/notifications/pkg/email/composer.go +++ b/services/notifications/pkg/email/composer.go @@ -2,29 +2,36 @@ package email import ( "bytes" + "embed" "strings" "text/template" - "github.com/owncloud/ocis/v2/services/notifications/pkg/email/l10n" + "github.com/owncloud/ocis/v2/ocis-pkg/l10n" +) + +var ( + //go:embed l10n/locale + _translationFS embed.FS + _domain = "notifications" ) // NewTextTemplate replace the body message template placeholders with the translated template func NewTextTemplate(mt MessageTemplate, locale, defaultLocale string, translationPath string, vars map[string]string) (MessageTemplate, error) { var err error - t := l10n.NewTranslator(locale, defaultLocale, translationPath) - mt.Subject, err = composeMessage(t.Translate(mt.Subject), vars) + t := l10n.NewTranslatorFromCommonConfig(defaultLocale, _domain, translationPath, _translationFS, "l10n/locale").Locale(locale) + mt.Subject, err = composeMessage(t.Get(mt.Subject), vars) if err != nil { return mt, err } - mt.Greeting, err = composeMessage(t.Translate(mt.Greeting), vars) + mt.Greeting, err = composeMessage(t.Get(mt.Greeting), vars) if err != nil { return mt, err } - mt.MessageBody, err = composeMessage(t.Translate(mt.MessageBody), vars) + mt.MessageBody, err = composeMessage(t.Get(mt.MessageBody), vars) if err != nil { return mt, err } - mt.CallToAction, err = composeMessage(t.Translate(mt.CallToAction), vars) + mt.CallToAction, err = composeMessage(t.Get(mt.CallToAction), vars) if err != nil { return mt, err } @@ -34,20 +41,20 @@ func NewTextTemplate(mt MessageTemplate, locale, defaultLocale string, translati // NewHTMLTemplate replace the body message template placeholders with the translated template func NewHTMLTemplate(mt MessageTemplate, locale, defaultLocale string, translationPath string, vars map[string]string) (MessageTemplate, error) { var err error - t := l10n.NewTranslator(locale, defaultLocale, translationPath) - mt.Subject, err = composeMessage(t.Translate(mt.Subject), vars) + t := l10n.NewTranslatorFromCommonConfig(defaultLocale, _domain, translationPath, _translationFS, "l10n/locale").Locale(locale) + mt.Subject, err = composeMessage(t.Get(mt.Subject), vars) if err != nil { return mt, err } - mt.Greeting, err = composeMessage(newlineToBr(t.Translate(mt.Greeting)), vars) + mt.Greeting, err = composeMessage(newlineToBr(t.Get(mt.Greeting)), vars) if err != nil { return mt, err } - mt.MessageBody, err = composeMessage(newlineToBr(t.Translate(mt.MessageBody)), vars) + mt.MessageBody, err = composeMessage(newlineToBr(t.Get(mt.MessageBody)), vars) if err != nil { return mt, err } - mt.CallToAction, err = composeMessage(callToActionToHTML(t.Translate(mt.CallToAction)), vars) + mt.CallToAction, err = composeMessage(callToActionToHTML(t.Get(mt.CallToAction)), vars) if err != nil { return mt, err } diff --git a/services/notifications/pkg/email/l10n/locate.go b/services/notifications/pkg/email/l10n/locate.go deleted file mode 100644 index 65ced72103..0000000000 --- a/services/notifications/pkg/email/l10n/locate.go +++ /dev/null @@ -1,51 +0,0 @@ -// Package l10n implements utility for translation the text templates. -// -// The l10n package use transifex translation for text templates. -package l10n - -import ( - "embed" - "io/fs" - - "github.com/leonelquinteros/gotext" -) - -var ( - //go:embed locale - _translationFS embed.FS - _domain = "notifications" -) - -// Translator is the interface to the translation -type Translator interface { - Translate(str string) string -} - -type translator struct { - locale *gotext.Locale -} - -// NewTranslator Create Translator with library path and language code and load default domain -func NewTranslator(locale, defaultLocale string, path string) Translator { - l := newLocate(locale, path) - if locale != "en" && len(l.GetTranslations()) == 0 { - l = newLocate(defaultLocale, path) - } - return &translator{locale: l} -} - -func newLocate(local string, path string) *gotext.Locale { - var l *gotext.Locale - if path == "" { - filesystem, _ := fs.Sub(_translationFS, "locale") - l = gotext.NewLocaleFS(local, filesystem) - } else { // use custom path instead - l = gotext.NewLocale(path, local) - } - l.AddDomain(_domain) // make domain configurable only if needed - return l -} - -func (t *translator) Translate(str string) string { - return t.locale.Get(str) -}