optimize SUI page writeLocaleSource and writeLocaleFiles logic

This commit is contained in:
Max 2024-07-17 08:25:52 +08:00
parent b7ba391278
commit 61f297b3dc
5 changed files with 307 additions and 38 deletions

View file

@ -36,6 +36,18 @@ func (ctx *BuildContext) GetJitComponents() []string {
return jitComponents return jitComponents
} }
// GetComponents get the components
func (ctx *BuildContext) GetComponents() []string {
if ctx.components == nil {
return []string{}
}
components := []string{}
for name := range ctx.components {
components = append(components, name)
}
return components
}
// GetTranslations get the translations // GetTranslations get the translations
func (ctx *BuildContext) GetTranslations() []Translation { func (ctx *BuildContext) GetTranslations() []Translation {
if ctx.translations == nil { if ctx.translations == nil {

69
sui/core/locale.go Normal file
View file

@ -0,0 +1,69 @@
package core
import (
"fmt"
"regexp"
)
// MergeTranslations merge the translations
func (locale *Locale) MergeTranslations(translations []Translation, prefix ...string) {
if locale.Keys == nil {
locale.Keys = map[string]string{}
}
if locale.Messages == nil {
locale.Messages = map[string]string{}
}
var reg *regexp.Regexp = nil
if len(prefix) > 0 && prefix[0] != "" {
reg = regexp.MustCompile(fmt.Sprintf(`^%s_([0-9]+)$`, prefix[0]))
}
for _, t := range translations {
// Keep only the keys that start with the keyPrefix
if reg != nil && !reg.MatchString(t.Key) {
continue
}
message := t.Message
if _, has := locale.Messages[message]; has {
message = locale.Messages[message]
}
locale.Keys[t.Key] = message
msg, has := locale.Messages[t.Message]
if has && msg != t.Message {
continue
}
locale.Messages[t.Message] = t.Message
}
}
// Merge merge the locale
func (locale *Locale) Merge(locale2 Locale) {
if locale2.Keys != nil {
if locale.Keys == nil {
locale.Keys = map[string]string{}
}
for key, value := range locale2.Keys {
if _, has := locale.Keys[key]; has {
continue
}
locale.Keys[key] = value
}
}
if locale2.Messages != nil {
if locale.Messages == nil {
locale.Messages = map[string]string{}
}
for key, value := range locale2.Messages {
if _, has := locale.Messages[key]; has {
continue
}
locale.Messages[key] = value
}
}
}

209
sui/core/locale_test.go Normal file
View file

@ -0,0 +1,209 @@
package core
import (
"testing"
)
func TestLocaleMergeTranslations(t *testing.T) {
tests := []struct {
name string
locale Locale
translations []Translation
prefix string
expectedKeys map[string]string
expectedMsgs map[string]string
}{
{
name: "Empty translations",
locale: Locale{
Keys: map[string]string{},
Messages: map[string]string{},
},
translations: []Translation{},
prefix: "",
expectedKeys: map[string]string{},
expectedMsgs: map[string]string{},
},
{
name: "Nil Keys and Messages",
locale: Locale{
Keys: nil,
Messages: nil,
},
translations: []Translation{
{Key: "greeting", Message: "Hello"},
},
prefix: "",
expectedKeys: map[string]string{
"greeting": "Hello",
},
expectedMsgs: map[string]string{
"Hello": "Hello",
},
},
{
name: "With prefix",
locale: Locale{
Keys: map[string]string{},
Messages: map[string]string{},
},
translations: []Translation{
{Key: "prefix_1", Message: "Hello"},
{Key: "other_1", Message: "World"},
},
prefix: "prefix",
expectedKeys: map[string]string{
"prefix_1": "Hello",
},
expectedMsgs: map[string]string{
"Hello": "Hello",
},
},
{
name: "Update existing keys and values",
locale: Locale{
Keys: map[string]string{
"greeting": "Hi",
},
Messages: map[string]string{
"Hi": "Hi",
},
},
translations: []Translation{
{Key: "greeting", Message: "Hello"},
},
prefix: "",
expectedKeys: map[string]string{
"greeting": "Hello",
},
expectedMsgs: map[string]string{
"Hi": "Hi",
"Hello": "Hello",
},
},
{
name: "Duplicate messages",
locale: Locale{
Keys: map[string]string{},
Messages: map[string]string{},
},
translations: []Translation{
{Key: "welcome", Message: "Hello"},
{Key: "farewell", Message: "Hello"},
},
prefix: "",
expectedKeys: map[string]string{
"welcome": "Hello",
"farewell": "Hello",
},
expectedMsgs: map[string]string{
"Hello": "Hello",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.locale.MergeTranslations(tt.translations, tt.prefix)
if !testCompareMaps(tt.locale.Keys, tt.expectedKeys) {
t.Errorf("expected keys %v, got %v", tt.expectedKeys, tt.locale.Keys)
}
if !testCompareMaps(tt.locale.Messages, tt.expectedMsgs) {
t.Errorf("expected messages %v, got %v", tt.expectedMsgs, tt.locale.Messages)
}
})
}
}
func TestLocaleMerge(t *testing.T) {
tests := []struct {
name string
locale Locale
locale2 Locale
expectedKeys map[string]string
expectedMsgs map[string]string
}{
{
name: "Nil Keys and Messages in locale2",
locale: Locale{
Keys: map[string]string{"greeting": "Hello"},
Messages: map[string]string{"Hello": "Hello"},
},
locale2: Locale{
Keys: nil,
Messages: nil,
},
expectedKeys: map[string]string{"greeting": "Hello"},
expectedMsgs: map[string]string{"Hello": "Hello"},
},
{
name: "Nil Keys and Messages in locale",
locale: Locale{
Keys: nil,
Messages: nil,
},
locale2: Locale{
Keys: map[string]string{"farewell": "Goodbye"},
Messages: map[string]string{"Goodbye": "Goodbye"},
},
expectedKeys: map[string]string{"farewell": "Goodbye"},
expectedMsgs: map[string]string{"Goodbye": "Goodbye"},
},
{
name: "Merge non-existing keys and messages",
locale: Locale{
Keys: map[string]string{"greeting": "Hello"},
Messages: map[string]string{"Hello": "Hello"},
},
locale2: Locale{
Keys: map[string]string{"farewell": "Goodbye"},
Messages: map[string]string{"Goodbye": "Goodbye"},
},
expectedKeys: map[string]string{
"greeting": "Hello",
"farewell": "Goodbye",
},
expectedMsgs: map[string]string{
"Hello": "Hello",
"Goodbye": "Goodbye",
},
},
{
name: "Merge with existing keys and messages",
locale: Locale{
Keys: map[string]string{"greeting": "Hello"},
Messages: map[string]string{"Hello": "Hello"},
},
locale2: Locale{
Keys: map[string]string{"greeting": "Hi"},
Messages: map[string]string{"Hello": "Hi"},
},
expectedKeys: map[string]string{"greeting": "Hello"},
expectedMsgs: map[string]string{"Hello": "Hello"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.locale.Merge(tt.locale2)
if !testCompareMaps(tt.locale.Keys, tt.expectedKeys) {
t.Errorf("expected keys %v, got %v", tt.expectedKeys, tt.locale.Keys)
}
if !testCompareMaps(tt.locale.Messages, tt.expectedMsgs) {
t.Errorf("expected messages %v, got %v", tt.expectedMsgs, tt.locale.Messages)
}
})
}
}
func testCompareMaps(a, b map[string]string) bool {
if len(a) != len(b) {
return false
}
for k, v := range a {
if b[k] != v {
return false
}
}
return true
}

View file

@ -80,8 +80,14 @@ func ComponentName(name string, hash ...bool) string {
// TranslationKey convert the name to translation key // TranslationKey convert the name to translation key
func TranslationKey(name string, sequence int) string { func TranslationKey(name string, sequence int) string {
prefix := TranslationKeyPrefix(name)
return fmt.Sprintf("%s_%d", prefix, sequence)
}
// TranslationKeyPrefix convert the name to translation key prefix
func TranslationKeyPrefix(name string) string {
name = strings.ReplaceAll(name, "/", "_") name = strings.ReplaceAll(name, "/", "_")
name = strings.ReplaceAll(name, "[", "_") name = strings.ReplaceAll(name, "[", "_")
name = strings.ReplaceAll(name, "]", "_") name = strings.ReplaceAll(name, "]", "_")
return fmt.Sprintf("trans_%s_%d", name, sequence) return fmt.Sprintf("trans_%s", name)
} }

View file

@ -495,25 +495,14 @@ func (page *Page) writeLocaleSource(ctx *core.BuildContext, option *core.BuildOp
} }
} }
prefix := core.TranslationKeyPrefix(page.Route)
for _, lc := range locales { for _, lc := range locales {
if lc.Default { if lc.Default {
continue continue
} }
locale := page.locale(lc.Value, true) locale := page.locale(lc.Value, true)
for _, t := range translations { locale.MergeTranslations(translations, prefix)
message := t.Message
// Match the key
if _, has := locale.Messages[message]; has {
message = locale.Messages[message]
}
locale.Keys[t.Key] = message
msg, has := locale.Messages[t.Message]
if has && msg != t.Message {
continue
}
locale.Messages[t.Message] = t.Message
}
// Call the hook // Call the hook
var keys any = locale.Keys var keys any = locale.Keys
@ -573,35 +562,19 @@ func (page *Page) writeLocaleFiles(ctx *core.BuildContext, data map[string]inter
} }
files := page.localeFiles(data) files := page.localeFiles(data)
components := ctx.GetComponents()
for name, file := range files { for name, file := range files {
// Init Data
keys := map[string]string{}
messages := map[string]string{}
for _, t := range translations {
keys[t.Key] = t.Message
messages[t.Message] = t.Message
}
locale := page.locale(name) locale := page.locale(name)
for key := range keys { locale.MergeTranslations(translations)
if _, has := locale.Keys[key]; has {
keys[key] = locale.Keys[key]
}
if msgValue, has := locale.Messages[keys[key]]; has { // Merge the components locale
keys[key] = msgValue for _, component := range components {
} compLocale := page.locale(component, true)
locale.Merge(compLocale)
} }
for message := range messages { // Remove messages
if _, has := locale.Messages[message]; has { locale.Messages = map[string]string{}
messages[message] = locale.Messages[message]
}
}
locale.Keys = keys
locale.Messages = messages
raw, err := yaml.Marshal(locale) raw, err := yaml.Marshal(locale)
if err != nil { if err != nil {
log.Error(`[SUI] Marshal the locale file error: %s`, err.Error()) log.Error(`[SUI] Marshal the locale file error: %s`, err.Error())