|
2 | 2 | > |
3 | 3 | > v1 of go-i18n is deprecated and no longer maintained. Please switch to [v2](https://pkg.go.dev/github.com/nicksnyder/go-i18n/v2). |
4 | 4 |
|
5 | | -# go-i18n [](http://travis-ci.org/nicksnyder/go-i18n) [](https://goreportcard.com/report/github.com/nicksnyder/go-i18n) [](https://sourcegraph.com/github.com/nicksnyder/go-i18n?badge) |
6 | | - |
7 | | -go-i18n is a Go [package](#package-i18n) and a [command](#command-goi18n) that helps you translate Go programs into multiple languages. |
8 | | - |
9 | | -- Supports [pluralized strings](http://cldr.unicode.org/index/cldr-spec/plural-rules) for all 200+ languages in the [Unicode Common Locale Data Repository (CLDR)](http://www.unicode.org/cldr/charts/28/supplemental/language_plural_rules.html). |
10 | | - - Code and tests are [automatically generated](https://github.com/nicksnyder/go-i18n/tree/master/i18n/language/codegen) from [CLDR data](http://cldr.unicode.org/index/downloads). |
11 | | -- Supports strings with named variables using [text/template](http://golang.org/pkg/text/template/) syntax. |
12 | | -- Supports message files of any format (e.g. JSON, TOML, YAML, etc.). |
13 | | -- [Documented](http://godoc.org/github.com/nicksnyder/go-i18n) and [tested](https://travis-ci.org/nicksnyder/go-i18n)! |
14 | | - |
15 | | -## Package i18n [](http://godoc.org/github.com/nicksnyder/go-i18n/v2/i18n) |
16 | | - |
17 | | -The i18n package provides support for looking up messages according to a set of locale preferences. |
18 | | - |
19 | | -```go |
20 | | -import "github.com/nicksnyder/go-i18n/v2/i18n" |
| 5 | +go-i18n [](http://travis-ci.org/nicksnyder/go-i18n) [](https://sourcegraph.com/github.com/nicksnyder/go-i18n?badge) |
| 6 | +======= |
| 7 | + |
| 8 | +go-i18n is a Go [package](#i18n-package) and a [command](#goi18n-command) that helps you translate Go programs into multiple languages. |
| 9 | +* Supports [pluralized strings](http://cldr.unicode.org/index/cldr-spec/plural-rules) for all 200+ languages in the [Unicode Common Locale Data Repository (CLDR)](http://www.unicode.org/cldr/charts/28/supplemental/language_plural_rules.html). |
| 10 | + * Code and tests are [automatically generated](https://github.com/nicksnyder/go-i18n/tree/master/i18n/language/codegen) from [CLDR data](http://cldr.unicode.org/index/downloads) |
| 11 | +* Supports strings with named variables using [text/template](http://golang.org/pkg/text/template/) syntax. |
| 12 | +* Translation files are simple JSON, TOML or YAML. |
| 13 | +* [Documented](http://godoc.org/github.com/nicksnyder/go-i18n) and [tested](https://travis-ci.org/nicksnyder/go-i18n)! |
| 14 | + |
| 15 | +Package i18n [](http://godoc.org/github.com/nicksnyder/go-i18n/i18n) |
| 16 | +------------ |
| 17 | + |
| 18 | +The i18n package provides runtime APIs for fetching translated strings. |
| 19 | + |
| 20 | +Command goi18n [](http://godoc.org/github.com/nicksnyder/go-i18n/goi18n) |
| 21 | +-------------- |
| 22 | + |
| 23 | +The goi18n command provides functionality for managing the translation process. |
| 24 | + |
| 25 | +Installation |
| 26 | +------------ |
| 27 | + |
| 28 | +Make sure you have [setup GOPATH](http://golang.org/doc/code.html#GOPATH). |
| 29 | + |
| 30 | + go get -u github.com/nicksnyder/go-i18n/goi18n |
| 31 | + goi18n -help |
| 32 | + |
| 33 | +Workflow |
| 34 | +-------- |
| 35 | + |
| 36 | +A typical workflow looks like this: |
| 37 | + |
| 38 | +1. Add a new string to your source code. |
| 39 | + |
| 40 | + ```go |
| 41 | + T("settings_title") |
| 42 | + ``` |
| 43 | + |
| 44 | +2. Add the string to en-US.all.json |
| 45 | + |
| 46 | + ```json |
| 47 | + [ |
| 48 | + { |
| 49 | + "id": "settings_title", |
| 50 | + "translation": "Settings" |
| 51 | + } |
| 52 | + ] |
| 53 | + ``` |
| 54 | + |
| 55 | +3. Run goi18n |
| 56 | + |
| 57 | + ``` |
| 58 | + goi18n path/to/*.all.json |
| 59 | + ``` |
| 60 | +
|
| 61 | +4. Send `path/to/*.untranslated.json` to get translated. |
| 62 | +5. Run goi18n again to merge the translations |
| 63 | +
|
| 64 | + ```sh |
| 65 | + goi18n path/to/*.all.json path/to/*.untranslated.json |
| 66 | + ``` |
| 67 | +
|
| 68 | +Translation files |
| 69 | +----------------- |
| 70 | +
|
| 71 | +A translation file stores translated and untranslated strings. |
| 72 | +
|
| 73 | +Here is an example of the default file format that go-i18n supports: |
| 74 | +
|
| 75 | +```json |
| 76 | +[ |
| 77 | + { |
| 78 | + "id": "d_days", |
| 79 | + "translation": { |
| 80 | + "one": "{{.Count}} day", |
| 81 | + "other": "{{.Count}} days" |
| 82 | + } |
| 83 | + }, |
| 84 | + { |
| 85 | + "id": "my_height_in_meters", |
| 86 | + "translation": { |
| 87 | + "one": "I am {{.Count}} meter tall.", |
| 88 | + "other": "I am {{.Count}} meters tall." |
| 89 | + } |
| 90 | + }, |
| 91 | + { |
| 92 | + "id": "person_greeting", |
| 93 | + "translation": "Hello {{.Person}}" |
| 94 | + }, |
| 95 | + { |
| 96 | + "id": "person_unread_email_count", |
| 97 | + "translation": { |
| 98 | + "one": "{{.Person}} has {{.Count}} unread email.", |
| 99 | + "other": "{{.Person}} has {{.Count}} unread emails." |
| 100 | + } |
| 101 | + }, |
| 102 | + { |
| 103 | + "id": "person_unread_email_count_timeframe", |
| 104 | + "translation": { |
| 105 | + "one": "{{.Person}} has {{.Count}} unread email in the past {{.Timeframe}}.", |
| 106 | + "other": "{{.Person}} has {{.Count}} unread emails in the past {{.Timeframe}}." |
| 107 | + } |
| 108 | + }, |
| 109 | + { |
| 110 | + "id": "program_greeting", |
| 111 | + "translation": "Hello world" |
| 112 | + }, |
| 113 | + { |
| 114 | + "id": "your_unread_email_count", |
| 115 | + "translation": { |
| 116 | + "one": "You have {{.Count}} unread email.", |
| 117 | + "other": "You have {{.Count}} unread emails." |
| 118 | + } |
| 119 | + } |
| 120 | +] |
21 | 121 | ``` |
22 | 122 |
|
23 | | -Create a Bundle to use for the lifetime of your application. |
| 123 | +To use a different file format, write a parser for the format and add the parsed translations using [AddTranslation](https://godoc.org/github.com/nicksnyder/go-i18n/i18n#AddTranslation). |
24 | 124 |
|
25 | | -```go |
26 | | -bundle := i18n.NewBundle(language.English) |
27 | | -``` |
| 125 | +Note that TOML only supports the flat format, which is described below. |
28 | 126 |
|
29 | | -Load translations into your bundle during initialization. |
| 127 | +More examples of translation files: [JSON](https://github.com/nicksnyder/go-i18n/tree/master/goi18n/testdata/input), [TOML](https://github.com/nicksnyder/go-i18n/blob/master/goi18n/testdata/input/flat/ar-ar.one.toml), [YAML](https://github.com/nicksnyder/go-i18n/blob/master/goi18n/testdata/input/yaml/en-us.one.yaml). |
30 | 128 |
|
31 | | -```go |
32 | | -bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) |
33 | | -bundle.LoadMessageFile("es.toml") |
34 | | -``` |
| 129 | +Flat Format |
| 130 | +------------- |
35 | 131 |
|
36 | | -Create a Localizer to use for a set of language preferences. |
| 132 | +You can also write shorter translation files with flat format. |
| 133 | +E.g the example above can be written in this way: |
37 | 134 |
|
38 | | -```go |
39 | | -func(w http.ResponseWriter, r *http.Request) { |
40 | | - lang := r.FormValue("lang") |
41 | | - accept := r.Header.Get("Accept-Language") |
42 | | - localizer := i18n.NewLocalizer(bundle, lang, accept) |
43 | | -} |
44 | | -``` |
45 | | - |
46 | | -Use the Localizer to lookup messages. |
47 | | - |
48 | | -```go |
49 | | -localizer.Localize(&i18n.LocalizeConfig{ |
50 | | - DefaultMessage: &i18n.Message{ |
51 | | - ID: "PersonCats", |
52 | | - One: "{{.Name}} has {{.Count}} cat.", |
53 | | - Other: "{{.Name}} has {{.Count}} cats.", |
54 | | - }, |
55 | | - TemplateData: map[string]interface{}{ |
56 | | - "Name": "Nick", |
57 | | - "Count": 2, |
58 | | - }, |
59 | | - PluralCount: 2, |
60 | | -}) // Nick has 2 cats. |
61 | | -``` |
| 135 | +```json |
| 136 | +{ |
| 137 | + "d_days": { |
| 138 | + "one": "{{.Count}} day.", |
| 139 | + "other": "{{.Count}} days." |
| 140 | + }, |
62 | 141 |
|
63 | | -## Command goi18n [](http://godoc.org/github.com/nicksnyder/go-i18n/v2/goi18n) |
| 142 | + "my_height_in_meters": { |
| 143 | + "one": "I am {{.Count}} meter tall.", |
| 144 | + "other": "I am {{.Count}} meters tall." |
| 145 | + }, |
64 | 146 |
|
65 | | -The goi18n command manages message files used by the i18n package. |
| 147 | + "person_greeting": { |
| 148 | + "other": "Hello {{.Person}}" |
| 149 | + }, |
66 | 150 |
|
67 | | -``` |
68 | | -go get -u github.com/nicksnyder/go-i18n/v2/goi18n |
69 | | -goi18n -help |
70 | | -``` |
| 151 | + "person_unread_email_count": { |
| 152 | + "one": "{{.Person}} has {{.Count}} unread email.", |
| 153 | + "other": "{{.Person}} has {{.Count}} unread emails." |
| 154 | + }, |
71 | 155 |
|
72 | | -### Extracting messages |
| 156 | + "person_unread_email_count_timeframe": { |
| 157 | + "one": "{{.Person}} has {{.Count}} unread email in the past {{.Timeframe}}.", |
| 158 | + "other": "{{.Person}} has {{.Count}} unread emails in the past {{.Timeframe}}." |
| 159 | + }, |
73 | 160 |
|
74 | | -Use `goi18n extract` to extract all i18n.Message struct literals in Go source files to a message file for translation. |
| 161 | + "program_greeting": { |
| 162 | + "other": "Hello world" |
| 163 | + }, |
75 | 164 |
|
76 | | -```toml |
77 | | -# active.en.toml |
78 | | -[PersonCats] |
79 | | -description = "The number of cats a person has" |
80 | | -one = "{{.Name}} has {{.Count}} cat." |
81 | | -other = "{{.Name}} has {{.Count}} cats." |
| 165 | + "your_unread_email_count": { |
| 166 | + "one": "You have {{.Count}} unread email.", |
| 167 | + "other": "You have {{.Count}} unread emails." |
| 168 | + } |
| 169 | +} |
82 | 170 | ``` |
83 | 171 |
|
84 | | -### Translating a new language |
85 | | - |
86 | | -1. Create an empty message file for the language that you want to add (e.g. `translate.es.toml`). |
87 | | -2. Run `goi18n merge active.en.toml translate.es.toml` to populate `translate.es.toml` with the mesages to be translated. |
88 | | - |
89 | | - ```toml |
90 | | - # translate.es.toml |
91 | | - [HelloPerson] |
92 | | - hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5" |
93 | | - other = "Hello {{.Name}}" |
94 | | - ``` |
95 | | - |
96 | | -3. After `translate.es.toml` has been translated, rename it to `active.es.toml`. |
97 | | - |
98 | | - ```toml |
99 | | - # active.es.toml |
100 | | - [HelloPerson] |
101 | | - hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5" |
102 | | - other = "Hola {{.Name}}" |
103 | | - ``` |
104 | | - |
105 | | -4. Load `active.es.toml` into your bundle. |
106 | | - |
107 | | - ```go |
108 | | - bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) |
109 | | - bundle.LoadMessageFile("active.es.toml") |
110 | | - ``` |
111 | | - |
112 | | -### Translating new messages |
113 | | - |
114 | | -If you have added new messages to your program: |
| 172 | +The logic of flat format is, what it is structure of structures |
| 173 | +and name of substructures (ids) should be always a string. |
| 174 | +If there is only one key in substructure and it is "other", then it's non-plural |
| 175 | +translation, else plural. |
115 | 176 |
|
116 | | -1. Run `goi18n extract` to update `active.en.toml` with the new messages. |
117 | | -2. Run `goi18n merge active.*.toml` to generate updated `translate.*.toml` files. |
118 | | -3. Translate all the messages in the `translate.*.toml` files. |
119 | | -4. Run `goi18n merge active.*.toml translate.*.toml` to merge the translated messages into the active message files. |
| 177 | +More examples of flat format translation files can be found in [goi18n/testdata/input/flat](https://github.com/nicksnyder/go-i18n/tree/master/goi18n/testdata/input/flat). |
120 | 178 |
|
121 | | -## For more information and examples: |
| 179 | +Contributions |
| 180 | +------------- |
122 | 181 |
|
123 | | -- Read the [documentation](http://godoc.org/github.com/nicksnyder/go-i18n/v2/i18n). |
124 | | -- Look at the [code examples](https://github.com/nicksnyder/go-i18n/blob/master/v2/i18n/example_test.go) and [tests](https://github.com/nicksnyder/go-i18n/blob/master/v2/i18n/localizer_test.go). |
125 | | -- Look at an example [application](https://github.com/nicksnyder/go-i18n/tree/master/v2/example). |
| 182 | +If you would like to submit a pull request, please |
126 | 183 |
|
127 | | -## License |
| 184 | +1. Write tests |
| 185 | +2. Format code with [goimports](https://github.com/bradfitz/goimports). |
| 186 | +3. Read the [common code review comments](https://github.com/golang/go/wiki/CodeReviewComments). |
128 | 187 |
|
| 188 | +License |
| 189 | +------- |
129 | 190 | go-i18n is available under the MIT license. See the [LICENSE](LICENSE) file for more info. |
0 commit comments