diff --git a/pkg/locale/load.go b/pkg/locale/load.go index b331c422c..53baff34f 100644 --- a/pkg/locale/load.go +++ b/pkg/locale/load.go @@ -178,20 +178,14 @@ func loadTranslations(lang *Language) (err error) { return } - // wraps JSON with namespaces under each app with a language tag: - // { : { 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()) diff --git a/pkg/locale/service.go b/pkg/locale/service.go index 02c1c278b..83bee7434 100644 --- a/pkg/locale/service.go +++ b/pkg/locale/service.go @@ -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 } diff --git a/system/rest/locales.go b/system/rest/locales.go index 77de20b80..a2c612ba9 100644 --- a/system/rest/locales.go +++ b/system/rest/locales.go @@ -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) }