move translation logic from notifications to own package

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
jkoberg
2024-03-25 13:14:01 +01:00
parent 0567dc4f70
commit e9d39cdcb3
3 changed files with 69 additions and 62 deletions

51
ocis-pkg/l10n/l10n.go Normal file
View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)
}