@@ -11,31 +11,23 @@ Universal Translator is an i18n Translator for Go/Golang using CLDR data + plura
1111
1212Why another i18n library?
1313--------------------------
14- I noticed that most libraries out there use static files for translations, which I'm not against just there is not option for coding it inline,
15- as well as having formats which do not handle all plural rules, or are overcomplicated. There is also very little in the way of helping the user
16- know about what plural translations are needed for each language, no easy grouping to say, display all translations for a page...
14+ Because none of the plural rules seem to be correct out there, including the previous implimentation of this package,
15+ so I took it upon myself to create [ locales] ( https://github.com/go-playground/locales ) for everyone to use; this package
16+ is a thin wrapper around [ locales] ( https://github.com/go-playground/locales ) in order to store and translate text for
17+ use in your applications.
1718
1819Features
1920--------
20- - [x] Rules added from [ CLDR] ( http://cldr.unicode.org/index/downloads ) data
21- - [x] Use fmt.Sprintf() for translation string parsing
22- - [x] Add Translations in code
23- - [x] Prints the supported plural rules for a given translators locale using translator.PrintPluralRules()
24- - [x] Plural Translations
25- - [x] Date, Time & DateTime formatting
26- - [x] Number, Whole Number formatting
27- - [x] Currency both standard & accounting, formatting i.e. -$1,234.50 vs ($1,234.50)
28- - [x] Handles BC and AD Dates. i.e. January 2, 300 BC
21+ - [x] Rules generated from the latest [ CLDR] ( http://cldr.unicode.org/index/downloads ) data, v29
22+ - [x] Contains Cardinal, Ordinal and Range Plural Rules
23+ - [x] Contains Month, Weekday and Timezone translations built in
24+ - [x] Contains Date & Time formatting functions
25+ - [x] Contains Number, Currency, Accounting and Percent formatting functions
26+ - [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
2927- [ ] Support loading translations from files
3028- [ ] Exporting translations to file, mainly for getting them professionally translated
3129- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated
32- - [ ] Printing of grouped translations, i.e. all transations for the homepage
33- - [ ] Tests for all languages, I need help with this one see below
34-
35- Full Language tests
36- --------------------
37- I could sure use your help adding tests for every language, it is a huge undertaking and I just don't have the free time to do it all at the moment;
38- any help would be ** greatly appreciated!!!!** please see [ issue] ( https://github.com/go-playground/universal-translator/issues/1 ) for details.
30+ - [ ] Tests for all languages, I need help with this, please see [ here] ( https://github.com/go-playground/locales/issues/1 )
3931
4032Installation
4133-----------
@@ -44,13 +36,7 @@ Use go get
4436
4537``` go
4638go get github.com /go -playground/universal-translator
47- ```
48-
49- or to update
50-
51- ``` go
52- go get -u github.com /go -playground/universal-translator
53- ```
39+ ```
5440
5541Usage
5642-------
@@ -59,120 +45,70 @@ package main
5945
6046import (
6147 " fmt"
62- " time"
6348
49+ " github.com/go-playground/locales"
6450 " github.com/go-playground/universal-translator"
65-
66- // DONE this way to avoid huge compile times + memory for all languages, although it would
67- // be nice for all applications to support all languages... that's not reality
68- _ " github.com/go-playground/universal-translator/resources/locales"
6951)
7052
53+ // only one instance as translators within are shared + goroutine safe
54+ var universalTraslator *ut.UniversalTranslator
55+
7156func main () {
72- trans , _ := ut.GetTranslator (" en" )
73-
74- trans.PrintPluralRules ()
75- // OUTPUT:
76- // Translator locale 'en' supported rules:
77- // - PluralRuleOne
78- // - PluralRuleOther
79-
80- // add a singular translation
81- trans.Add (ut.PluralRuleOne , " homepage" , " welcome_msg" , " Welcome to site %s " )
82-
83- // add singular + plural translation(s)
84- trans.Add (ut.PluralRuleOne , " homepage" , " day_warning" , " You only have %d day left in your trial" )
85- trans.Add (ut.PluralRuleOther , " homepage" , " day_warning" , " You only have %d day's left in your trial" )
86-
87- // translate singular
88- translated := trans.T (" welcome_msg" , " Joey Bloggs" )
89- fmt.Println (translated)
90- // OUTPUT: Welcome to site Joey Bloggs
91-
92- // What if something went wrong? then translated would output "" (blank)
93- // How do I catch errors?
94- translated , err := trans.TSafe (" welcome_m" , " Joey Bloggs" )
95- fmt.Println (translated)
96- // OUTPUT: ""
97- fmt.Println (err)
98- // OUTPUT: ***** WARNING:***** Translation Key 'welcome_m' Not Found
99-
100- // NOTE: there is a Safe variant of most of the Translation and Formatting functions if you need them,
101- // for brevity will be using the non safe ones for the rest of this example
102-
103- // The second parameter below, count, is needed as the final variable is a varadic and would not
104- // know which one to use in applying the plural rules.
105- // translate singular/plural
106- translated = trans.P (" day_warning" , 3 , 3 )
107- fmt.Println (translated)
108- // OUTPUT: You only have 3 day's left in your trial
109-
110- translated = trans.P (" day_warning" , 1 , 1 )
111- fmt.Println (translated)
112- // OUTPUT: You only have 1 day left in your trial
113-
114- // There are Full, Long, Medium and Short function for each of the following
115- dtString := " Jan 2, 2006 at 3:04:05pm"
116- dt , _ := time.Parse (dtString, dtString)
117-
118- formatted := trans.FmtDateFull (dt)
119- fmt.Println (formatted)
120- // OUTPUT: Monday, January 2, 2006
121-
122- formatted = trans.FmtDateShort (dt)
123- fmt.Println (formatted)
124- // OUTPUT: 1/2/06
125-
126- formatted = trans.FmtTimeFull (dt)
127- fmt.Println (formatted)
128- // OUTPUT: 3:04:05 PM
129-
130- formatted = trans.FmtDateTimeFull (dt)
131- fmt.Println (formatted)
132- // OUTPUT: Monday, January 2, 2006 at 3:04:05 PM
133-
134- formatted = trans.FmtCurrency (ut.CurrencyStandard , " USD" , 1234.50 )
135- fmt.Println (formatted)
136- // OUTPUT: $1,234.50
137-
138- formatted = trans.FmtCurrency (ut.CurrencyStandard , " USD" , -1234.50 )
139- fmt.Println (formatted)
140- // OUTPUT: -$1,234.50
141-
142- formatted = trans.FmtCurrency (ut.CurrencyAccounting , " USD" , -1234.50 )
143- fmt.Println (formatted)
144- // OUTPUT: ($1,234.50)
145-
146- formatted = trans.FmtCurrencyWhole (ut.CurrencyStandard , " USD" , -1234.50 )
147- fmt.Println (formatted)
148- // OUTPUT: -$1,234
149-
150- formatted = trans.FmtNumber (1234.50 )
151- fmt.Println (formatted)
152- // OUTPUT: 1,234.5
153-
154- formatted = trans.FmtNumberWhole (1234.50 )
155- fmt.Println (formatted)
156- // OUTPUT: 1,234
57+
58+ // NOTE: this example is omitting allot of error checking for brevity
59+
60+ universalTraslator, _ = ut.New (" en" , " en" , " en_CA" , " nl" , " fr" )
61+
62+ en := universalTraslator.GetTranslator (" en" )
63+
64+ // generally used after parsing an http 'Accept-Language' header
65+ // and this will try to find a matching locale you support or
66+ // fallback locale.
67+ // en, _ := ut.FindTranslator([]string{"en", "en_CA", "nl"})
68+
69+ // this will help
70+ fmt.Println (" Cardinal Plural Rules:" , en.PluralsCardinal ())
71+ fmt.Println (" Ordinal Plural Rules:" , en.PluralsOrdinal ())
72+ fmt.Println (" Range Plural Rules:" , en.PluralsRange ())
73+
74+ // add basic language only translations
75+ en.Add (" welcome" , " Welcome {0} to our test" )
76+
77+ // add language translations dependant on cardinal plural rules
78+ en.AddCardinal (" days" , " You have {0} day left to register" , locales.PluralRuleOne )
79+ en.AddCardinal (" days" , " You have {0} days left to register" , locales.PluralRuleOther )
80+
81+ // add language translations dependant on ordinal plural rules
82+ en.AddOrdinal (" day-of-month" , " {0}st" , locales.PluralRuleOne )
83+ en.AddOrdinal (" day-of-month" , " {0}nd" , locales.PluralRuleTwo )
84+ en.AddOrdinal (" day-of-month" , " {0}rd" , locales.PluralRuleFew )
85+ en.AddOrdinal (" day-of-month" , " {0}th" , locales.PluralRuleOther )
86+
87+ // add language translations dependant on range plural rules
88+ // NOTE: only one plural rule for range in 'en' locale
89+ en.AddRange (" between" , " It's {0}-{1} days away" , locales.PluralRuleOther )
90+
91+ // now lets use the translations we just added, in the same order we added them
92+
93+ fmt.Println (en.T (" welcome" , " Joeybloggs" ))
94+
95+ fmt.Println (en.C (" days" , 1 , 0 , string (en.FmtNumber (1 , 0 )))) // you'd normally have variables defined for 1 and 0
96+ fmt.Println (en.C (" days" , 2 , 0 , string (en.FmtNumber (2 , 0 ))))
97+ fmt.Println (en.C (" days" , 10456.25 , 2 , string (en.FmtNumber (10456.25 , 2 ))))
98+
99+ fmt.Println (en.O (" day-of-month" , 1 , 0 , string (en.FmtNumber (1 , 0 ))))
100+ fmt.Println (en.O (" day-of-month" , 2 , 0 , string (en.FmtNumber (2 , 0 ))))
101+ fmt.Println (en.O (" day-of-month" , 3 , 0 , string (en.FmtNumber (3 , 0 ))))
102+ fmt.Println (en.O (" day-of-month" , 4 , 0 , string (en.FmtNumber (4 , 0 ))))
103+ fmt.Println (en.O (" day-of-month" , 10456.25 , 0 , string (en.FmtNumber (10456.25 , 0 ))))
104+
105+ fmt.Println (en.R (" between" , 0 , 0 , 1 , 0 , string (en.FmtNumber (0 , 0 )), string (en.FmtNumber (1 , 0 ))))
106+ fmt.Println (en.R (" between" , 1 , 0 , 2 , 0 , string (en.FmtNumber (1 , 0 )), string (en.FmtNumber (2 , 0 ))))
107+ fmt.Println (en.R (" between" , 1 , 0 , 100 , 0 , string (en.FmtNumber (1 , 0 )), string (en.FmtNumber (100 , 0 ))))
157108}
158109```
159110
160111Help With Tests
161112---------------
162113To anyone interesting in helping or contributing, I sure could use some help creating tests for each language.
163- Please see issue [ here] ( https://github.com/go-playground/universal-translator/issues/1 ) for details.
164-
165- Thanks to some help, the following languages have tests:
166-
167- - [x] en - English US
168- - [x] th - Thai thanks to @prideloki
169-
170- Special Thanks
171- --------------
172- Special thanks to the following libraries that not only inspired, but that I borrowed a bunch of code from to create this.. ultimately there were many changes made and more to come, but without them would have taken forever to just get started.
173- * [ cldr] ( https://github.com/theplant/cldr ) - A golang i18n tool using CLDR data
174- * [ i18n] ( https://github.com/vube/i18n ) - golang package for basic i18n features, including message translation and number formatting
175-
176- Misc
177- -------
178- Library is not at 1.0 yet, but don't forsee any major API changes; will raise to 1.0 once I've used it completely in at least one project without issue.
114+ Please see issue [ here] ( https://github.com/go-playground/locales/issues/1 ) for details.
0 commit comments