3
0

Resource translation improvements

* Fix locale context management
* Assure proper locale context parameters are used when updating,
  listing translations
* Return missing module field translations
This commit is contained in:
Tomaž Jerman 2021-09-20 18:53:31 +02:00
parent 8668e15ad8
commit fc9061fee3
7 changed files with 198 additions and 8 deletions

View File

@ -27,6 +27,36 @@ func (svc resourceTranslationsManager) moduleExtended(ctx context.Context, res *
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldDescriptionView
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldDescriptionEdit
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldHintView
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldHintEdit
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
// Extra field bits
converted, err := svc.moduleFieldValidatorErrorHandler(ctx, tag, f, k.Path)
if err != nil {

View File

@ -368,7 +368,7 @@ func (svc module) updater(ctx context.Context, namespaceID, moduleID uint64, act
tt = append(tt, f.EncodeTranslations()...)
}
tt.SetLanguage(locale.GetAcceptLanguageFromContext(ctx))
tt.SetLanguage(contentLang)
err = svc.locale.Upsert(ctx, tt)
if err != nil {
return err

View File

@ -296,7 +296,7 @@ func (svc page) Create(ctx context.Context, new *types.Page) (*types.Page, error
// i18n
if contentLang := locale.GetContentLanguageFromContext(ctx); contentLang != language.Und {
tt := new.EncodeTranslations()
tt.SetLanguage(locale.GetAcceptLanguageFromContext(ctx))
tt.SetLanguage(contentLang)
err = svc.locale.Upsert(ctx, tt)
if err != nil {
return err
@ -374,7 +374,7 @@ func (svc page) updater(ctx context.Context, namespaceID, pageID uint64, action
// i18n
if contentLang := locale.GetContentLanguageFromContext(ctx); contentLang != language.Und {
tt := p.EncodeTranslations()
tt.SetLanguage(locale.GetAcceptLanguageFromContext(ctx))
tt.SetLanguage(contentLang)
err = svc.locale.Upsert(ctx, tt)
if err != nil {
return err

View File

@ -48,6 +48,30 @@ var (
Resource: ModuleFieldResourceTranslationType,
Path: "label",
}
LocaleKeyModuleFieldDescriptionView = LocaleKey{
Name: "descriptionView",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.description.view",
CustomHandler: "descriptionView",
}
LocaleKeyModuleFieldDescriptionEdit = LocaleKey{
Name: "descriptionEdit",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.description.edit",
CustomHandler: "descriptionEdit",
}
LocaleKeyModuleFieldHintView = LocaleKey{
Name: "hintView",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.hint.view",
CustomHandler: "hintView",
}
LocaleKeyModuleFieldHintEdit = LocaleKey{
Name: "hintEdit",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.hint.edit",
CustomHandler: "hintEdit",
}
LocaleKeyModuleFieldValidatorError = LocaleKey{
Name: "validatorError",
Resource: ModuleFieldResourceTranslationType,
@ -178,6 +202,10 @@ func (r *ModuleField) DecodeTranslations(tt locale.ResourceTranslationIndex) {
if aux = tt.FindByKey(LocaleKeyModuleFieldLabel.Path); aux != nil {
r.Label = aux.Msg
}
r.decodeTranslationsDescriptionView(tt)
r.decodeTranslationsDescriptionEdit(tt)
r.decodeTranslationsHintView(tt)
r.decodeTranslationsHintEdit(tt)
r.decodeTranslationsValidatorError(tt)
}
@ -191,6 +219,10 @@ func (r *ModuleField) EncodeTranslations() (out locale.ResourceTranslationSet) {
})
}
out = append(out, r.encodeTranslationsDescriptionView()...)
out = append(out, r.encodeTranslationsDescriptionEdit()...)
out = append(out, r.encodeTranslationsHintView()...)
out = append(out, r.encodeTranslationsHintEdit()...)
out = append(out, r.encodeTranslationsValidatorError()...)
return out

View File

@ -10,6 +10,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/locale"
"github.com/spf13/cast"
)
type (
@ -66,6 +67,38 @@ func (f *ModuleField) decodeTranslationsValidatorError(tt locale.ResourceTransla
}
}
func (f *ModuleField) decodeTranslationsDescriptionView(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldDescriptionView.Path); aux != nil {
f.setOptionKey(aux.Msg, "description", "edit")
}
}
func (f *ModuleField) decodeTranslationsDescriptionEdit(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldDescriptionEdit.Path); aux != nil {
f.setOptionKey(aux.Msg, "description", "view")
}
}
func (f *ModuleField) decodeTranslationsHintView(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldHintView.Path); aux != nil {
f.setOptionKey(aux.Msg, "hint", "edit")
}
}
func (f *ModuleField) decodeTranslationsHintEdit(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldHintEdit.Path); aux != nil {
f.setOptionKey(aux.Msg, "hint", "view")
}
}
func (m *ModuleField) encodeTranslationsValidatorError() (out locale.ResourceTranslationSet) {
out = make(locale.ResourceTranslationSet, 0, 3)
@ -86,10 +119,99 @@ func (m *ModuleField) encodeTranslationsValidatorError() (out locale.ResourceTra
return
}
func (f *ModuleField) encodeTranslationsDescriptionView() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
v := f.getOptionKey("description", "edit")
aux := cast.ToString(v)
if aux != "" {
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldDescriptionView.Path,
Msg: aux,
})
}
return out
}
func (f *ModuleField) encodeTranslationsDescriptionEdit() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
v := f.getOptionKey("description", "view")
aux := cast.ToString(v)
if aux != "" {
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldDescriptionEdit.Path,
Msg: aux,
})
}
return out
}
func (f *ModuleField) encodeTranslationsHintView() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
v := f.getOptionKey("hint", "edit")
aux := cast.ToString(v)
if aux != "" {
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldHintView.Path,
Msg: aux,
})
}
return out
}
func (f *ModuleField) encodeTranslationsHintEdit() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
v := f.getOptionKey("hint", "view")
aux := cast.ToString(v)
if aux != "" {
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldHintEdit.Path,
Msg: aux,
})
}
return out
}
func (m ModuleField) Clone() *ModuleField {
return &m
}
func (m ModuleField) setOptionKey(v interface{}, kk ...string) {
opt := m.Options
for _, k := range kk[0 : len(kk)-1] {
_, ok := opt[k]
if !ok {
opt = map[string]interface{}{k: make(map[string]interface{})}
}
aux := opt[k].(map[string]interface{})
opt = aux
}
k := kk[len(kk)-1]
opt[k] = v
}
func (m ModuleField) getOptionKey(kk ...string) interface{} {
opt := m.Options
for _, k := range kk[0 : len(kk)-1] {
_, ok := opt[k]
if !ok {
opt = map[string]interface{}{k: make(map[string]interface{})}
}
aux := opt[k].(map[string]interface{})
opt = aux
}
return opt[kk[len(kk)-1]]
}
func (set ModuleFieldSet) Clone() (out ModuleFieldSet) {
out = make([]*ModuleField, len(set))
for i := range set {

View File

@ -17,8 +17,8 @@ locale:
skipSvc: true
keys:
- label
# - { name: descriptionView, path: meta.description.view, custom: true }
# - { name: descriptionEdit, path: meta.description.edit, custom: true }
# - { name: hintView, path: meta.hint.view, custom: true }
# - { name: hintEdit, path: meta.hint.edit, custom: true }
- { name: descriptionView, path: meta.description.view, custom: true, customHandler: descriptionView }
- { name: descriptionEdit, path: meta.description.edit, custom: true, customHandler: descriptionEdit }
- { name: hintView, path: meta.hint.view, custom: true, customHandler: hintView }
- { name: hintEdit, path: meta.hint.edit, custom: true, customHandler: hintEdit }
- { name: validatorError, path: "expression.validator.{{validatorID}}.error", custom: true, customHandler: validatorError }

View File

@ -16,9 +16,11 @@ func DetectLanguage(ll *service) func(next http.Handler) http.Handler {
var ctx = r.Context()
// resolve accept-language header
// Accept-Language specifies the language of the response payload.
ctx = SetAcceptLanguageToContext(ctx, resolveAcceptLanguageHeaders(ll, r))
// resolve content-language header
// Content-Language specifies the language of the request payload.
ctx = SetContentLanguageToContext(ctx, resolveContentLanguageHeaders(r.Header, ll.Default().Tag))
next.ServeHTTP(w, r.WithContext(ctx))
@ -37,7 +39,11 @@ func DetectLanguage(ll *service) func(next http.Handler) http.Handler {
func resolveContentLanguageHeaders(h http.Header, def language.Tag) language.Tag {
var cLang = h.Get(ContentLanguageHeader)
if cLang == "skip" || cLang == "" {
if cLang == "" {
return def
}
if cLang == "skip" {
// more than 1 header or value equal to skip
return language.Und
}