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
|
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
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
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue