optimize SUI page writeLocaleSource and writeLocaleFiles logic
This commit is contained in:
parent
b7ba391278
commit
61f297b3dc
5 changed files with 307 additions and 38 deletions
|
|
@ -36,6 +36,18 @@ func (ctx *BuildContext) GetJitComponents() []string {
|
|||
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
|
||||
func (ctx *BuildContext) GetTranslations() []Translation {
|
||||
if ctx.translations == nil {
|
||||
|
|
|
|||
69
sui/core/locale.go
Normal file
69
sui/core/locale.go
Normal 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
209
sui/core/locale_test.go
Normal 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
|
||||
}
|
||||
|
|
@ -80,8 +80,14 @@ func ComponentName(name string, hash ...bool) string {
|
|||
|
||||
// TranslationKey convert the name to translation key
|
||||
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, "]", "_")
|
||||
return fmt.Sprintf("trans_%s_%d", name, sequence)
|
||||
return fmt.Sprintf("trans_%s", name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -495,25 +495,14 @@ func (page *Page) writeLocaleSource(ctx *core.BuildContext, option *core.BuildOp
|
|||
}
|
||||
}
|
||||
|
||||
prefix := core.TranslationKeyPrefix(page.Route)
|
||||
for _, lc := range locales {
|
||||
if lc.Default {
|
||||
continue
|
||||
}
|
||||
|
||||
locale := page.locale(lc.Value, true)
|
||||
for _, t := range translations {
|
||||
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
|
||||
}
|
||||
locale.MergeTranslations(translations, prefix)
|
||||
|
||||
// Call the hook
|
||||
var keys any = locale.Keys
|
||||
|
|
@ -573,35 +562,19 @@ func (page *Page) writeLocaleFiles(ctx *core.BuildContext, data map[string]inter
|
|||
}
|
||||
|
||||
files := page.localeFiles(data)
|
||||
components := ctx.GetComponents()
|
||||
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)
|
||||
for key := range keys {
|
||||
if _, has := locale.Keys[key]; has {
|
||||
keys[key] = locale.Keys[key]
|
||||
}
|
||||
locale.MergeTranslations(translations)
|
||||
|
||||
if msgValue, has := locale.Messages[keys[key]]; has {
|
||||
keys[key] = msgValue
|
||||
}
|
||||
// Merge the components locale
|
||||
for _, component := range components {
|
||||
compLocale := page.locale(component, true)
|
||||
locale.Merge(compLocale)
|
||||
}
|
||||
|
||||
for message := range messages {
|
||||
if _, has := locale.Messages[message]; has {
|
||||
messages[message] = locale.Messages[message]
|
||||
}
|
||||
}
|
||||
|
||||
locale.Keys = keys
|
||||
locale.Messages = messages
|
||||
// Remove messages
|
||||
locale.Messages = map[string]string{}
|
||||
raw, err := yaml.Marshal(locale)
|
||||
if err != nil {
|
||||
log.Error(`[SUI] Marshal the locale file error: %s`, err.Error())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue