Skip to content

Commit 79ffd2c

Browse files
committed
v1.0.0
1 parent 27c78ad commit 79ffd2c

7 files changed

Lines changed: 314 additions & 0 deletions

File tree

data.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package gogo_i18n
2+
3+
import "golang.org/x/text/language"
4+
5+
type (
6+
//GoGoi18nMessageInterface
7+
GoGoi18nMessageInterface interface {
8+
TableName() string
9+
GetI18nJSONData() map[string]map[string]map[string]string
10+
}
11+
//GoGoi18nMessage 資料庫欄位
12+
GoGoi18nMessage struct {
13+
ID uint64 `json:"id" yaml:"-" gorm:"type:bigint(20) unsigned auto_increment;not null;primary_key"`
14+
Language string `json:"language" gorm:"unique_index:idx1;comment:'語言別'"`
15+
Key string `json:"key" gorm:"unique_index:idx1;comment:'多語的key'"`
16+
Value string `json:"value" gorm:"unique_index:idx1;comment:'多語的值'"`
17+
}
18+
)
19+
20+
func NewGoGoi18nMessage(language language.Tag, key string, value string) GoGoi18nMessageInterface {
21+
return &GoGoi18nMessage{
22+
Language: language.String(),
23+
Key: key,
24+
Value: value,
25+
}
26+
}
27+
28+
//TableName 修改資料庫 Table 名稱
29+
func (g *GoGoi18nMessage) TableName() string {
30+
return "i18n"
31+
}
32+
33+
//GetI18nJSONData 取得 i18n 轉換後的資料
34+
func (g *GoGoi18nMessage) GetI18nJSONData() map[string]map[string]map[string]string {
35+
return map[string]map[string]map[string]string{
36+
g.Language: {
37+
g.Key: {
38+
"other": g.Value,
39+
},
40+
},
41+
}
42+
}

example/main.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
. "github.com/codingXiang/gogo-i18n"
7+
"golang.org/x/text/language"
8+
)
9+
10+
type Test struct {
11+
Model string
12+
}
13+
14+
func main() {
15+
//設定 i18n 翻譯資料
16+
var (
17+
i18nDatas = []GoGoi18nMessageInterface{
18+
NewGoGoi18nMessage(language.TraditionalChinese, "orm.create.success", "建立 {{.Data}} 成功"),
19+
NewGoGoi18nMessage(language.TraditionalChinese, "orm.create.failed", "建立 {{.Data}} 失敗,原因為 {{.Error}}"),
20+
NewGoGoi18nMessage(language.TraditionalChinese, "orm.update.success", "更新 {{.Data}} 成功"),
21+
NewGoGoi18nMessage(language.TraditionalChinese, "orm.update.failed", "更新 {{.Data}} 失敗,原因為 {{.Error}}"),
22+
NewGoGoi18nMessage(language.TraditionalChinese, "orm.get.success", "取得 {{.Data}} 成功"),
23+
NewGoGoi18nMessage(language.TraditionalChinese, "orm.get.failed", "取得 {{.Data}} 失敗,原因為 {{.Error}}"),
24+
NewGoGoi18nMessage(language.English, "orm.create.success", "Create {{.Data}} success"),
25+
NewGoGoi18nMessage(language.English, "orm.create.failed", "Create {{.Data}} failed,because {{.Error}}"),
26+
NewGoGoi18nMessage(language.English, "orm.update.success", "Update {{.Data}} success"),
27+
NewGoGoi18nMessage(language.English, "orm.update.failed", "Update {{.Data}} failed,because {{.Error}}"),
28+
NewGoGoi18nMessage(language.English, "orm.get.success", "Get {{.Data}} success"),
29+
NewGoGoi18nMessage(language.English, "orm.get.failed", "Get {{.Data}} failed,because {{.Error}}"),
30+
}
31+
)
32+
//儲存資料至檔案中
33+
StoreDataToFile("yaml", "/Users/user/go/src/pkg/gogo-i18n/example", i18nDatas)
34+
35+
// 建立 GoGoi18n 物件,預設語言為中文
36+
GGi18n = NewGoGoi18n(language.TraditionalChinese)
37+
// 設定 Config 類別
38+
GGi18n.SetFileType("yaml")
39+
// 讀取 語言檔案
40+
GGi18n.LoadTranslationFile("/Users/user/go/src/pkg/gogo-i18n/example",
41+
language.TraditionalChinese,
42+
language.English)
43+
// 正確訊息翻譯
44+
msg := GGi18n.GetMessage("orm.create.success", map[string]interface{}{
45+
"Data": "User",
46+
})
47+
// 錯誤訊息翻譯
48+
msgErr := GGi18n.GetMessage("orm.update.failed", map[string]interface{}{
49+
"Data": "User",
50+
"Error": errors.New("錯誤"),
51+
})
52+
fmt.Println(msg)
53+
fmt.Println(msgErr)
54+
55+
//更換語言別為英文
56+
GGi18n.SetUseLanguage(language.English)
57+
msg1 := GGi18n.GetMessage("orm.create.success", map[string]string{
58+
"Data": "User",
59+
})
60+
msg1Err := GGi18n.GetMessage("orm.get.failed", map[string]interface{}{
61+
"Data": "User",
62+
"Error": errors.New("err"),
63+
})
64+
fmt.Println(msg1)
65+
fmt.Println(msg1Err)
66+
67+
// 重新設定物件,變更預設語系為英文
68+
GGi18n.Reload(language.English)
69+
}

example/yaml/en.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- orm.create.success:
2+
other: Create {{.Data}} success
3+
- orm.create.failed:
4+
other: Create {{.Data}} failed,because {{.Error}}
5+
- orm.update.success:
6+
other: Update {{.Data}} success
7+
- orm.update.failed:
8+
other: Update {{.Data}} failed,because {{.Error}}
9+
- orm.get.success:
10+
other: Get {{.Data}} success
11+
- orm.get.failed:
12+
other: Get {{.Data}} failed,because {{.Error}}

example/yaml/zh-Hant.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- orm.create.success:
2+
other: 建立 {{.Data}} 成功
3+
- orm.create.failed:
4+
other: 建立 {{.Data}} 失敗,原因為 {{.Error}}
5+
- orm.update.success:
6+
other: 更新 {{.Data}} 成功
7+
- orm.update.failed:
8+
other: 更新 {{.Data}} 失敗,原因為 {{.Error}}
9+
- orm.get.success:
10+
other: 取得 {{.Data}} 成功
11+
- orm.get.failed:
12+
other: 取得 {{.Data}} 失敗,原因為 {{.Error}}

go.mod

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module github.com/codingXiang/gogo-i18n
2+
3+
go 1.13
4+
5+
require (
6+
github.com/BurntSushi/toml v0.3.1 // indirect
7+
github.com/kr/pretty v0.1.0 // indirect
8+
github.com/nicksnyder/go-i18n/v2 v2.0.3
9+
golang.org/x/text v0.3.2
10+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
11+
gopkg.in/yaml.v2 v2.2.8
12+
)

go.sum

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2+
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
3+
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
4+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
5+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
6+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
7+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
8+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
9+
github.com/nicksnyder/go-i18n/v2 v2.0.3 h1:ks/JkQiOEhhuF6jpNvx+Wih1NIiXzUnZeZVnJuI8R8M=
10+
github.com/nicksnyder/go-i18n/v2 v2.0.3/go.mod h1:oDab7q8XCYMRlcrBnaY/7B1eOectbvj6B1UPBT+p5jo=
11+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
12+
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
13+
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
14+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
15+
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
16+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
17+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
18+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
19+
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
21+
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
22+
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
23+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
24+
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
25+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
26+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
27+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
28+
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
29+
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
30+
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

i18n.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package gogo_i18n
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
i18n2 "github.com/nicksnyder/go-i18n/v2/i18n"
7+
"golang.org/x/text/language"
8+
"gopkg.in/yaml.v2"
9+
"io/ioutil"
10+
"os"
11+
)
12+
13+
type (
14+
//GoGoi18nInterface GoGoi18n 的實作介面
15+
GoGoi18nInterface interface {
16+
Reload(lang language.Tag) GoGoi18nInterface
17+
SetFileType(t string) error
18+
SetUseLanguage(lang language.Tag)
19+
LoadTranslationFile(path string, langs ...language.Tag) error
20+
GetMessage(messageID string, data interface{}) string
21+
}
22+
//GoGoi18n 封裝 go-i18n 的結構
23+
GoGoi18n struct {
24+
bundle *i18n2.Bundle //go-i18n 內的 bundle
25+
fileType string //檔案類型
26+
local *i18n2.Localizer //翻譯語言設定參數
27+
}
28+
)
29+
30+
var (
31+
GGi18n GoGoi18nInterface //i18n 實例
32+
)
33+
34+
//NewGoGoi18n 建立 GoGoi18n 實例
35+
func NewGoGoi18n(lang language.Tag) GoGoi18nInterface {
36+
var instance = &GoGoi18n{
37+
bundle: i18n2.NewBundle(lang),
38+
}
39+
instance.local = i18n2.NewLocalizer(instance.bundle, lang.String())
40+
return instance
41+
}
42+
43+
//Reload 重新讀取語言包
44+
func (i *GoGoi18n) Reload(lang language.Tag) GoGoi18nInterface {
45+
i.bundle = i18n2.NewBundle(lang)
46+
i.local = i18n2.NewLocalizer(i.bundle, lang.String())
47+
return i
48+
}
49+
50+
//SetFileType 設定翻譯檔類型
51+
func (i *GoGoi18n) SetFileType(t string) error {
52+
i.fileType = t
53+
switch t {
54+
case "json":
55+
i.bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
56+
break
57+
case "yaml":
58+
i.bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)
59+
break
60+
default:
61+
return errors.New("not support file type " + t + ", can use `json` or `yaml`.")
62+
}
63+
return nil
64+
}
65+
66+
//SetUseLanguage 設定當前要翻譯的語言
67+
func (i *GoGoi18n) SetUseLanguage(lang language.Tag) {
68+
i.local = i18n2.NewLocalizer(i.bundle, lang.String())
69+
}
70+
71+
//LoadTranslationFile 讀取翻譯檔
72+
func (i *GoGoi18n) LoadTranslationFile(path string, langs ...language.Tag) error {
73+
for _, lang := range langs {
74+
f := path + "/" + i.fileType + "/" + lang.String() + "." + i.fileType
75+
if _, err := i.bundle.LoadMessageFile(f); err != nil {
76+
return err
77+
}
78+
}
79+
return nil
80+
}
81+
82+
//GetMessage 取得翻譯後的訊息
83+
func (i *GoGoi18n) GetMessage(messageID string, data interface{}) string {
84+
return i.local.MustLocalize(&i18n2.LocalizeConfig{
85+
MessageID: messageID,
86+
TemplateData: data,
87+
})
88+
}
89+
90+
func StoreDataToFile(fileType string, path string, datas []GoGoi18nMessageInterface) error {
91+
var (
92+
rs = make(map[string][]map[string]map[string]string)
93+
method = json.Marshal
94+
err error
95+
)
96+
97+
//初始化路徑
98+
path = path + "/" + fileType + "/"
99+
100+
for _, data := range datas {
101+
for key, value := range data.GetI18nJSONData() {
102+
rs[key] = append(rs[key], value)
103+
}
104+
}
105+
//判斷路徑是否存在
106+
if _, err := os.Stat(path); os.IsNotExist(err) {
107+
//建立路徑
108+
if err = os.MkdirAll(path, os.FileMode(0755)); err != nil {
109+
return err
110+
}
111+
}
112+
113+
//選擇要轉換的檔案類型
114+
switch fileType {
115+
case "json":
116+
method = json.Marshal
117+
break;
118+
case "yaml":
119+
method = yaml.Marshal
120+
break;
121+
}
122+
123+
//開始進行存檔
124+
for key, data := range rs {
125+
var (
126+
fileName = path + key + "." + fileType
127+
)
128+
if decoder, err := method(data); err != nil {
129+
return err
130+
} else {
131+
if err = ioutil.WriteFile(fileName, decoder, os.ModePerm); err != nil {
132+
return err
133+
}
134+
}
135+
}
136+
return err
137+
}

0 commit comments

Comments
 (0)