Handle multi-lang request for external translation
Frontend/client lib (i18next) sends request for multiple languages at the same time (format: en+sl+de). Some internal changes on ext. translation loading (storing) were needed.
This commit is contained in:
+3
-9
@@ -178,20 +178,14 @@ func loadTranslations(lang *Language) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// wraps JSON with namespaces under each app with a language tag:
|
||||
// { <lang>: { namespace ..., namespace ... } }
|
||||
//
|
||||
// This simplifies and unifies the output and makes it compatible
|
||||
// with the frontend libs
|
||||
// encode all external (for webapps, clientS) translations
|
||||
// into buffers that will be copied directly into responses
|
||||
for app, nss := range auxExternal {
|
||||
var (
|
||||
buf = &bytes.Buffer{}
|
||||
aux = make(map[string]interface{})
|
||||
)
|
||||
|
||||
aux[lang.Tag.String()] = nss
|
||||
|
||||
if err = json.NewEncoder(buf).Encode(aux); err != nil {
|
||||
if err = json.NewEncoder(buf).Encode(nss); err != nil {
|
||||
return
|
||||
}
|
||||
lang.external[app] = bytes.NewReader(buf.Bytes())
|
||||
|
||||
+14
-7
@@ -64,7 +64,7 @@ func Service(log *zap.Logger, opt options.LocaleOpt) (*service, error) {
|
||||
lang = strings.TrimSpace(lang)
|
||||
tag := language.Make(lang)
|
||||
if tag.IsRoot() {
|
||||
return nil, fmt.Errorf("failed to parse language '%s'", lang)
|
||||
return nil, fmt.Errorf("failed to parse language '%s' (did you use comma to separate them?)", lang)
|
||||
}
|
||||
|
||||
svc.tags = append(svc.tags, tag)
|
||||
@@ -220,16 +220,23 @@ func (svc *service) HasApplication(lang language.Tag, app string) bool {
|
||||
}
|
||||
|
||||
// EncodeExternal writes into
|
||||
func (svc *service) EncodeExternal(w io.Writer, lang language.Tag, app string) (err error) {
|
||||
func (svc *service) EncodeExternal(w io.Writer, app string, ll ...language.Tag) (err error) {
|
||||
svc.l.RLock()
|
||||
defer svc.l.RUnlock()
|
||||
|
||||
if svc.HasApplication(lang, app) {
|
||||
svc.set[lang].external[app].Seek(0, 0)
|
||||
_, err = io.Copy(w, svc.set[lang].external[app])
|
||||
} else {
|
||||
err = fmt.Errorf("application or language missing")
|
||||
fmt.Fprint(w, "{")
|
||||
for i, lang := range ll {
|
||||
if i > 0 {
|
||||
fmt.Fprint(w, ",")
|
||||
}
|
||||
|
||||
if svc.HasApplication(lang, app) {
|
||||
fmt.Fprintf(w, "%q:", lang)
|
||||
svc.set[lang].external[app].Seek(0, 0)
|
||||
_, _ = io.Copy(w, svc.set[lang].external[app])
|
||||
}
|
||||
}
|
||||
fmt.Fprint(w, "}")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
+37
-15
@@ -3,6 +3,7 @@ package rest
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/errors"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
@@ -46,31 +47,52 @@ func (ctrl Locale) List(ctx context.Context, r *request.LocaleList) (interface{}
|
||||
func (ctrl Locale) Get(ctx context.Context, r *request.LocaleGet) (interface{}, error) {
|
||||
svc := locale.Global()
|
||||
|
||||
// We're using + as a language delimiter
|
||||
// because webapp client i18n lib does this by default
|
||||
// (url encoded space becomes a +)
|
||||
const langSplit = "+"
|
||||
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
if !svc.HasLanguage(language.Make(r.Lang)) {
|
||||
// @todo temp workaround until frontend knows what languages it can use
|
||||
r.Lang = svc.List()[0].Tag.String()
|
||||
}
|
||||
|
||||
if !svc.HasLanguage(language.Make(r.Lang)) {
|
||||
if len(svc.List()) == 0 {
|
||||
errors.ProperlyServeHTTP(w, req, errors.New(
|
||||
errors.KindNotFound,
|
||||
"no such language",
|
||||
"no languages found",
|
||||
errors.StackTrimAtFn("http.HandlerFunc.ServeHTTP"),
|
||||
), true)
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.HasApplication(language.Make(r.Lang), r.Application) {
|
||||
errors.ProperlyServeHTTP(w, req, errors.New(
|
||||
errors.KindNotFound,
|
||||
"no such application",
|
||||
errors.StackTrimAtFn("http.HandlerFunc.ServeHTTP"),
|
||||
), true)
|
||||
return
|
||||
// default to 1st language
|
||||
//var def = svc.List()[0].Tag
|
||||
var ll = []language.Tag{}
|
||||
|
||||
for _, candidate := range strings.Split(r.Lang, langSplit) {
|
||||
ll = append(ll, language.Make(candidate))
|
||||
//if svc.HasLanguage(tmp) {
|
||||
// ll = append(ll, lang)
|
||||
// break
|
||||
//}
|
||||
}
|
||||
|
||||
if err := locale.Global().EncodeExternal(w, language.Make(r.Lang), r.Application); err != nil {
|
||||
//if !svc.HasLanguage(lang) {
|
||||
// errors.ProperlyServeHTTP(w, req, errors.New(
|
||||
// errors.KindNotFound,
|
||||
// "no such language",
|
||||
// errors.StackTrimAtFn("http.HandlerFunc.ServeHTTP"),
|
||||
// ), true)
|
||||
// return
|
||||
//}
|
||||
|
||||
//if !svc.HasApplication(lang, r.Application) {
|
||||
// errors.ProperlyServeHTTP(w, req, errors.New(
|
||||
// errors.KindNotFound,
|
||||
// "no such application",
|
||||
// errors.StackTrimAtFn("http.HandlerFunc.ServeHTTP"),
|
||||
// ), true)
|
||||
// return
|
||||
//}
|
||||
|
||||
if err := locale.Global().EncodeExternal(w, r.Application, ll...); err != nil {
|
||||
errors.ProperlyServeHTTP(w, req, err, true)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user