From a00ea001fbc0dd6d04d0a2f3205451709218280b Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 23 Jun 2025 21:36:40 +0200 Subject: [PATCH] init --- .gitignore | 1 + example_translations/de.json | 4 ++ example_translations/en.json | 4 ++ example_translations/files.go | 6 +++ example_translations/fr.json | 4 ++ go.mod | 3 ++ translation.go | 59 ++++++++++++++++++++++++++++ translation_test.go | 72 +++++++++++++++++++++++++++++++++++ 8 files changed, 153 insertions(+) create mode 100644 .gitignore create mode 100644 example_translations/de.json create mode 100644 example_translations/en.json create mode 100644 example_translations/files.go create mode 100644 example_translations/fr.json create mode 100644 go.mod create mode 100644 translation.go create mode 100644 translation_test.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/example_translations/de.json b/example_translations/de.json new file mode 100644 index 0000000..ee1c2c6 --- /dev/null +++ b/example_translations/de.json @@ -0,0 +1,4 @@ +{ + "KEY": "WERT", + "WITH_PARAM": "WERT %[1]s_%[2]s" +} diff --git a/example_translations/en.json b/example_translations/en.json new file mode 100644 index 0000000..b8354f3 --- /dev/null +++ b/example_translations/en.json @@ -0,0 +1,4 @@ +{ + "KEY": "VALUE", + "WITH_PARAM": "VALUE %[1]s_%[2]s" +} diff --git a/example_translations/files.go b/example_translations/files.go new file mode 100644 index 0000000..ae2fd4b --- /dev/null +++ b/example_translations/files.go @@ -0,0 +1,6 @@ +package exampletranslations + +import "embed" + +//go:embed *.json +var Files embed.FS diff --git a/example_translations/fr.json b/example_translations/fr.json new file mode 100644 index 0000000..ddffaea --- /dev/null +++ b/example_translations/fr.json @@ -0,0 +1,4 @@ +{ + "KEY": "VALEUR", + "WITH_PARAM": "VALEUR %[1]s_%[2]s" +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bb30189 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.apihub24.de/admin/translation + +go 1.22.0 diff --git a/translation.go b/translation.go new file mode 100644 index 0000000..28ab77d --- /dev/null +++ b/translation.go @@ -0,0 +1,59 @@ +package translation + +import ( + "embed" + "encoding/json" + "fmt" + "strings" +) + +var defaultCulture = "en" +var sources = make(map[string]map[string]string) +var translationFiles embed.FS + +func SetDefaultCulture(culture string) { + defaultCulture = strings.ToLower(culture) +} + +func Init(files embed.FS) { + translationFiles = files +} + +func Get(key string, culture string, args ...string) string { + source, err := loadSource(culture) + if err != nil { + return fmt.Sprintf("unknown error: %s", err.Error()) + } + value, ok := source[key] + if !ok { + return fmt.Sprintf("no value for key %s found in source %s", key, culture) + } + if len(args) > 0 { + var tmpArgs = make([]any, len(args)) + for idx, arg := range args { + tmpArgs[idx] = arg + } + return fmt.Sprintf(value, tmpArgs...) + } + return value +} + +func loadSource(culture string) (map[string]string, error) { + source, ok := sources[culture] + if ok { + return source, nil + } + data, err := translationFiles.ReadFile(fmt.Sprintf("%s.json", strings.ToLower(culture))) + if err != nil { + data, err = translationFiles.ReadFile(fmt.Sprintf("%s.json", defaultCulture)) + if err != nil { + return source, fmt.Errorf("can not load translation source for culture %s DefaultCulture: %s", culture, defaultCulture) + } + } + err = json.Unmarshal(data, &source) + if err != nil { + return source, fmt.Errorf("can not parse translation source %s", culture) + } + sources[culture] = source + return sources[culture], nil +} diff --git a/translation_test.go b/translation_test.go new file mode 100644 index 0000000..4acce67 --- /dev/null +++ b/translation_test.go @@ -0,0 +1,72 @@ +package translation_test + +import ( + "testing" + + "git.apihub24.de/admin/translation" + exampletranslations "git.apihub24.de/admin/translation/example_translations" +) + +func Test_Translation_Init(t *testing.T) { + translation.Init(exampletranslations.Files) + if translation.Get("KEY", "de") != "WERT" { + t.Errorf("translations not initialized!") + } +} + +func Test_Translation_Get_de(t *testing.T) { + translation.Init(exampletranslations.Files) + value := translation.Get("KEY", "de") + if value != "WERT" { + t.Errorf("expect German KEY to have Value 'WERT' but was %s", value) + } +} + +func Test_Translation_Get_en(t *testing.T) { + translation.Init(exampletranslations.Files) + value := translation.Get("KEY", "en") + if value != "VALUE" { + t.Errorf("expect English KEY to have Value 'VALUE' but was %s", value) + } +} + +func Test_Translation_Get_fr(t *testing.T) { + translation.Init(exampletranslations.Files) + value := translation.Get("KEY", "fr") + if value != "VALEUR" { + t.Errorf("expect France KEY to have Value 'VALEUR' but was %s", value) + } +} + +func Test_Translation_Get_Fallback_en(t *testing.T) { + translation.Init(exampletranslations.Files) + value := translation.Get("KEY", "notexists") + if value != "VALUE" { + t.Errorf("expect Fallback KEY to have Value 'VALUE' but was %s", value) + } +} + +func Test_Translation_Can_Change_Fallback_Language(t *testing.T) { + translation.Init(exampletranslations.Files) + translation.SetDefaultCulture("de") + value := translation.Get("KEY", "notexists") + if value != "WERT" { + t.Errorf("expect Fallback KEY to have Value 'WERT' but was %s", value) + } +} + +func Test_Translation_Get_With_Parameter(t *testing.T) { + translation.Init(exampletranslations.Files) + valueDe := translation.Get("WITH_PARAM", "de", "a", "b") + valueEn := translation.Get("WITH_PARAM", "en", "a", "b") + valueFr := translation.Get("WITH_PARAM", "fr", "a", "b") + if valueDe != "WERT a_b" { + t.Errorf("expect German KEY to have Value 'WERT a_b' but was %s", valueDe) + } + if valueEn != "VALUE a_b" { + t.Errorf("expect English KEY to have Value 'VALUE a_b' but was %s", valueEn) + } + if valueFr != "VALEUR a_b" { + t.Errorf("expect France KEY to have Value 'VALEUR a_b' but was %s", valueFr) + } +}