Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(i18n/gi18n): add key-value translation pattern #3829

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ go.work.sum
node_modules
.docusaurus
output
config/*
3 changes: 3 additions & 0 deletions cmd/gf/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.18

require (
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.7.2
github.com/gogf/gf/contrib/drivers/dm/v2 v2.7.1
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.7.2
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.2
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.7.2
Expand All @@ -18,6 +19,7 @@ require (

require (
aead.dev/minisign v0.2.0 // indirect
gitee.com/chunanyong/dm v1.8.12 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.0.15 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
Expand All @@ -31,6 +33,7 @@ require (
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
Expand Down
14 changes: 14 additions & 0 deletions cmd/gf/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.7.2 h1:ieOB/AaYmRyLnFc/t5HMMpWXTEJ+A9O+d9AcWnIizQs=
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.7.2/go.mod h1:TfTV5FErx1SGjQM100MkuO390Iy+BO1sPZ0OMm2Q5N4=
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.7.2 h1:+rnLsVwFCNG294D3dJmhbfPz7dG+qA7JOnlL6cYk55Y=
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.7.2/go.mod h1:nxAQjtQtcbGrF705gkTxdc032c/MNY28sCyWYQrD1Fw=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.2 h1:GpE2JuHVoNJD4lNP1omC1+TKXNCSvXr5oil1bNULYd0=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.2/go.mod h1:0h3UmNAmA8hnjvTyozZelSWWxiAjGDQttzZqMhkCkJo=
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.7.2 h1:EAcV1aIbFyZwsFkXmqVuOoz5JwuTybDNRFpTDNKQtLo=
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.7.2/go.mod h1:XUo35CiDBTJ9T3K5VkiEnQzphEPq+lRHft6s8XWun74=
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.7.2 h1:tI4V57XyvKIpCX8WUtyGlh6aN+rFcg2reKnDqbhxuLA=
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.7.2/go.mod h1:IB+g+oXMF6SZQQY4Ec8Kh3c3LddfEkgIsmYBAc3CsKM=
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.7.2 h1:P/1w0jayiYZUd3X7EFuZ7r5FinBupNhWf8BzJkB2V9Y=
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.7.2/go.mod h1:TSNhyUnkedVxHOHbFlr4hVMxpNXklF80kz1gjLlCIuE=
github.com/gogf/gf/v2 v2.7.2 h1:uZDfyblasI12lZUtFd1mfxsIr8b14cd/F88DJUTCSDM=
github.com/gogf/gf/v2 v2.7.2/go.mod h1:EBXneAg/wes86rfeh68XC0a2JBNQylmT7Sp6/8Axk88=
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f h1:7xfXR/BhG3JDqO1s45n65Oyx9t4E/UqDOXep6jXdLCM=
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f/go.mod h1:HnYoio6S7VaFJdryKcD/r9HgX+4QzYfr00XiXUo/xz0=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
Expand Down
25 changes: 24 additions & 1 deletion i18n/gi18n/gi18n_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,33 @@ func (m *Manager) Tf(ctx context.Context, format string, values ...interface{})
return m.TranslateFormat(ctx, format, values...)
}

// Tm is alias of TranslateMap for convenience.
func (m *Manager) Tm(ctx context.Context, context string, valMap map[string]interface{}) string {
return m.TranslateMap(ctx, context, valMap)
}

// TranslateFormat translates, formats and returns the `format` with configured language
// and given `values`.
// When values[0] is of type map[string]string, parameter replacement is order-independent.
// the values' format :{key}
func (m *Manager) TranslateFormat(ctx context.Context, format string, values ...interface{}) string {
return fmt.Sprintf(m.Translate(ctx, format), values...)
result := m.Translate(ctx, format)
return fmt.Sprintf(result, values...)
}

// TranslateMap parameter replacement is order-independent.
// replaced param format is :{key}. for example: content is "my name is :name.",the valMap is map[string]interface{}{"name":"alias"}
// the result of translation is "my name is alias."
func (m *Manager) TranslateMap(ctx context.Context, content string, valMap map[string]interface{}) string {
result := m.Translate(ctx, content)
mpStrStr := gconv.MapStrStr(valMap)
if len(mpStrStr) > 0 {
for k, v := range mpStrStr {
rpKey := ":" + k
result = strings.ReplaceAll(result, rpKey, v)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 我不确定:key这种模式是否最优雅的替换方式,可以参考其他i18n的转译是使用的什么格式来做的替换。
  • 这里直接使用ReplaceAll似乎也不是很优雅,例如有两个变量:key1:key2,在替换的时候使用key则会把它们都替换掉了。

}
}
return result
}

// Translate translates `content` with configured language.
Expand Down
13 changes: 13 additions & 0 deletions i18n/gi18n/gi18n_z_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package gi18n_test

import (
"fmt"
"time"

"github.com/gogf/gf/v2/encoding/gbase64"
Expand Down Expand Up @@ -91,6 +92,18 @@ func Test_TranslateFormat(t *testing.T) {
})
}

func Test_TranslateMap(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
i18n := gi18n.New(gi18n.Options{
Path: gtest.DataPath("i18n-file"),
})
i18n.SetLanguage("zh-CN")
str := i18n.Tm(context.Background(), "replace_map_test", map[string]interface{}{"name": "blue", "score": "3000"})
fmt.Println(str)
t.Assert(str, "hello 3000 blue is ok")
})
}

func Test_DefaultManager(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
err := gi18n.SetPath(gtest.DataPath("i18n"))
Expand Down
3 changes: 2 additions & 1 deletion i18n/gi18n/testdata/i18n-file/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"你好": "hello",
"世界": "world",
"hello": "你好",
"world": "世界"
"world": "世界",
"replace_map_test": "hello :score :name is ok"
}
31 changes: 16 additions & 15 deletions net/gclient/gclient_z_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func init() {
if err != nil {
panic(err)
}
time.Sleep(time.Millisecond * 500)
time.Sleep(time.Millisecond * 2000)
}

func ExampleNew() {
Expand Down Expand Up @@ -195,7 +195,7 @@ func ExampleNew_MultiConn_Recommend() {
if r, err := client.Get(ctx, "http://127.0.0.1:8999/var/json"); err != nil {
panic(err)
} else {
fmt.Println(r.ReadAllString())
fmt.Print(r.ReadAllString())
r.Close()
}
}
Expand Down Expand Up @@ -272,9 +272,9 @@ func ExampleClient_ContentJson() {
}
)
// Post using JSON string.
fmt.Println(g.Client().ContentJson().PostContent(ctx, url, jsonStr))
fmt.Print(g.Client().ContentJson().PostContent(ctx, url, jsonStr))
// Post using JSON map.
fmt.Println(g.Client().ContentJson().PostContent(ctx, url, jsonMap))
fmt.Print(g.Client().ContentJson().PostContent(ctx, url, jsonMap))

// Output:
// Content-Type: application/json, id: 10000
Expand All @@ -289,7 +289,7 @@ func ExampleClient_Post() {
panic(err)
}
defer r1.Close()
fmt.Println(r1.ReadAllString())
fmt.Print(r1.ReadAllString())

// Send with map parameter.
r2, err := g.Client().Post(ctx, url, g.Map{
Expand All @@ -300,7 +300,7 @@ func ExampleClient_Post() {
panic(err)
}
defer r2.Close()
fmt.Println(r2.ReadAllString())
fmt.Print(r2.ReadAllString())

// Output:
// POST: form: 10000, john
Expand Down Expand Up @@ -425,15 +425,15 @@ func ExampleClient_Get() {
panic(err)
}
defer r1.Close()
fmt.Println(r1.ReadAllString())
fmt.Print(r1.ReadAllString())

// Send with string parameter in request body.
r2, err := g.Client().Get(ctx, url, "id=10000&name=john")
if err != nil {
panic(err)
}
defer r2.Close()
fmt.Println(r2.ReadAllString())
fmt.Print(r2.ReadAllString())

// Send with map parameter.
r3, err := g.Client().Get(ctx, url, g.Map{
Expand All @@ -444,7 +444,7 @@ func ExampleClient_Get() {
panic(err)
}
defer r3.Close()
fmt.Println(r3.ReadAllString())
fmt.Print(r3.ReadAllString())

// Output:
// GET: query: 10000, john
Expand Down Expand Up @@ -596,16 +596,16 @@ func ExampleClient_Proxy() {

client2 := g.Client()
_, err = client2.Proxy("socks5://127.0.0.1:1080").Get(ctx, "http://127.0.0.1:8999")
fmt.Println(err != nil)
fmt.Print(err != nil)

client3 := g.Client()
_, err = client3.Proxy("").Get(ctx, "http://127.0.0.1:8999")
fmt.Println(err != nil)
fmt.Print(err != nil)

client4 := g.Client()
url := "http://127.0.0.1:1081" + string([]byte{0x7f})
_, err = client4.Proxy(url).Get(ctx, "http://127.0.0.1:8999")
fmt.Println(err != nil)
fmt.Print(err != nil)

// Output:
// true
Expand Down Expand Up @@ -639,7 +639,7 @@ func ExampleClient_Prefix() {
"http://127.0.0.1:%d/api/v1/", s.GetListenedPort(),
))

fmt.Println(string(client.GetBytes(ctx, "prefix")))
fmt.Print(string(client.GetBytes(ctx, "prefix")))
fmt.Println(string(client.GetBytes(ctx, "hello")))

// Output:
Expand Down Expand Up @@ -742,7 +742,7 @@ func ExampleClient_SetRedirectLimit() {
"name": "john",
})
if err == nil {
fmt.Println(resp.ReadAllString())
fmt.Print(resp.ReadAllString())
resp.Close()
}

Expand All @@ -752,12 +752,13 @@ func ExampleClient_SetRedirectLimit() {
"name": "john",
})
if err == nil {
fmt.Println(resp.ReadAllString())
fmt.Print(resp.ReadAllString())
resp.Close()
}

// Output:
// Found
//
// hello world
}

Expand Down