Selaa lähdekoodia

update README + code cleanup

joeybloggs 9 vuotta sitten
vanhempi
commit
460f747984
5 muutettua tiedostoa jossa 274 lisäystä ja 23 poistoa
  1. 153 2
      README.md
  2. 100 0
      examples/basic/main.go
  3. BIN
      logo.png
  4. 19 19
      number.go
  5. 2 2
      translator.go

+ 153 - 2
README.md

@@ -1,3 +1,154 @@
-# universal-translator
-i18n Translator for Go/Golang using CLDR data
+## universal-translator
+<img align="right" src="https://raw.githubusercontent.com/go-playground/universal-translator/master/logo.png">
+![Project status](https://img.shields.io/badge/version-0.8.0-green.svg)
+[![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator)
+![License](https://img.shields.io/dub/l/vibe-d.svg)
 
+Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules
+
+Why another i18n library?
+--------------------------
+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, 
+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
+know about what plural translations are needed for each language, no easy grouping to say, display all translations for a page...
+
+Features
+--------
+- [x] Rules added from [CLDR](http://cldr.unicode.org/index/downloads) data
+- [x] Use fmt.Sprintf() for translation string parsing
+- [x] Add Translations in code
+- [x] Prints the supported plural rules for a given translators locale using translator.PrintPluralRules()
+- [x] Plural Translations
+- [x] Date, Time & DateTime formatting
+- [x] Number, Whole Number formatting
+- [x] Currency both standard & accounting, formatting i.e. -$1,234.50 vs ($1,234.50)
+- [ ] Support loading translations from files
+- [ ] Exporting translations to file, mainly for getting them professionally translated
+- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated
+- [ ] Printing of grouped translations, i.e. all transations for the homepage
+- [ ] Tests for all languages, I need help with this one see below
+
+Full Language tests
+--------------------
+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;
+any help would be **greatly appreciated!!!!** please see issue x for details.
+
+Installation
+-----------
+
+Use go get 
+
+```go
+go get github.com/go-playground/universal-translator
+``` 
+
+or to update
+
+```go
+go get -u github.com/go-playground/universal-translator
+``` 
+
+Usage
+-------
+```go
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/go-playground/universal-translator"
+
+	// DONE this way to avoid huge compile times + memory for all languages, although it would
+	// be nice for all applications to support all languages... that's not reality
+	_ "github.com/go-playground/universal-translator/resources/locales"
+)
+
+func main() {
+	trans, _ := ut.GetTranslator("en")
+
+	trans.PrintPluralRules()
+	// OUTPUT:
+	// Translator locale 'en' supported rules:
+	//- PluralRuleOne
+	//- PluralRuleOther
+
+	// add a singular translation
+	trans.Add(ut.PluralRuleOne, "homepage", "welcome_msg", "Welcome to site %s")
+
+	// add singular + plural translation(s)
+	trans.Add(ut.PluralRuleOne, "homepage", "day_warning", "You only have %d day left in your trial")
+	trans.Add(ut.PluralRuleOther, "homepage", "day_warning", "You only have %d day's left in your trial")
+
+	// translate singular
+	translated := trans.T("welcome_msg", "Joey Bloggs")
+	fmt.Println(translated)
+	// OUTPUT: Welcome to site Joey Bloggs
+
+	// What if something went wrong? then translated would output "" (blank)
+	// How do I catch errors?
+	translated, err := trans.TSafe("welcome_m", "Joey Bloggs")
+	fmt.Println(translated)
+	// OUTPUT: ""
+	fmt.Println(err)
+	// OUTPUT: ***** WARNING:***** Translation Key 'welcome_m' Not Found
+
+	// NOTE: there is a Safe variant of most of the Translation and Formatting functions if you need them,
+	// for brevity will be using the non safe ones for the rest of this example
+
+	// The second parameter below, count, is needed as the final variable is a varadic and would not
+	// know which one to use in applying the plural rules.
+	// translate singular/plural
+	translated = trans.P("day_warning", 3, 3)
+	fmt.Println(translated)
+	// OUTPUT: You only have 3 day's left in your trial
+
+	translated = trans.P("day_warning", 1, 1)
+	fmt.Println(translated)
+	// OUTPUT: You only have 1 day left in your trial
+
+	// There are Full, Long, Medium and Short function for each of the following
+	dtString := "Jan 2, 2006 at 3:04:05pm"
+	dt, _ := time.Parse(dtString, dtString)
+
+	formatted := trans.FmtDateFull(dt)
+	fmt.Println(formatted)
+	// OUTPUT: Monday, January 2, 2006
+
+	formatted = trans.FmtDateShort(dt)
+	fmt.Println(formatted)
+	// OUTPUT: 1/2/06
+
+	formatted = trans.FmtTimeFull(dt)
+	fmt.Println(formatted)
+	// OUTPUT: 3:04:05 PM
+
+	formatted = trans.FmtDateTimeFull(dt)
+	fmt.Println(formatted)
+	// OUTPUT: Monday, January 2, 2006 at 3:04:05 PM
+
+	formatted = trans.FmtCurrency(ut.CurrencyStandard, "USD", 1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: $1,234.50
+
+	formatted = trans.FmtCurrency(ut.CurrencyStandard, "USD", -1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: -$1,234.50
+
+	formatted = trans.FmtCurrency(ut.CurrencyAccounting, "USD", -1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: ($1,234.50)
+
+	formatted = trans.FmtCurrencyWhole(ut.CurrencyStandard, "USD", -1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: -$1,234
+
+	formatted = trans.FmtNumber(1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: 1,234.5
+
+	formatted = trans.FmtNumberWhole(1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: 1,234
+}
+```

+ 100 - 0
examples/basic/main.go

@@ -0,0 +1,100 @@
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/go-playground/universal-translator"
+
+	// DONE this way to avoid huge compile times + memory for all languages, although it would
+	// be nice for all applications to support all languages... that's not reality
+	_ "github.com/go-playground/universal-translator/resources/locales"
+)
+
+func main() {
+	trans, _ := ut.GetTranslator("en")
+
+	trans.PrintPluralRules()
+	// OUTPUT:
+	// Translator locale 'en' supported rules:
+	//- PluralRuleOne
+	//- PluralRuleOther
+
+	// add a singular translation
+	trans.Add(ut.PluralRuleOne, "homepage", "welcome_msg", "Welcome to site %s")
+
+	// add singular + plural translation(s)
+	trans.Add(ut.PluralRuleOne, "homepage", "day_warning", "You only have %d day left in your trial")
+	trans.Add(ut.PluralRuleOther, "homepage", "day_warning", "You only have %d day's left in your trial")
+
+	// translate singular
+	translated := trans.T("welcome_msg", "Joey Bloggs")
+	fmt.Println(translated)
+	// OUTPUT: Welcome to site Joey Bloggs
+
+	// What if something went wrong? then translated would output "" (blank)
+	// How do I catch errors?
+	translated, err := trans.TSafe("welcome_m", "Joey Bloggs")
+	fmt.Println(translated)
+	// OUTPUT: ""
+	fmt.Println(err)
+	// OUTPUT: ***** WARNING:***** Translation Key 'welcome_m' Not Found
+
+	// NOTE: there is a Safe variant of most of the Translation and Formatting functions if you need them,
+	// for brevity will be using the non safe ones for the rest of this example
+
+	// The second parameter below, count, is needed as the final variable is a varadic and would not
+	// know which one to use in applying the plural rules.
+	// translate singular/plural
+	translated = trans.P("day_warning", 3, 3)
+	fmt.Println(translated)
+	// OUTPUT: You only have 3 day's left in your trial
+
+	translated = trans.P("day_warning", 1, 1)
+	fmt.Println(translated)
+	// OUTPUT: You only have 1 day left in your trial
+
+	// There are Full, Long, Medium and Short function for each of the following
+	dtString := "Jan 2, 2006 at 3:04:05pm"
+	dt, _ := time.Parse(dtString, dtString)
+
+	formatted := trans.FmtDateFull(dt)
+	fmt.Println(formatted)
+	// OUTPUT: Monday, January 2, 2006
+
+	formatted = trans.FmtDateShort(dt)
+	fmt.Println(formatted)
+	// OUTPUT: 1/2/06
+
+	formatted = trans.FmtTimeFull(dt)
+	fmt.Println(formatted)
+	// OUTPUT: 3:04:05 PM
+
+	formatted = trans.FmtDateTimeFull(dt)
+	fmt.Println(formatted)
+	// OUTPUT: Monday, January 2, 2006 at 3:04:05 PM
+
+	formatted = trans.FmtCurrency(ut.CurrencyStandard, "USD", 1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: $1,234.50
+
+	formatted = trans.FmtCurrency(ut.CurrencyStandard, "USD", -1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: -$1,234.50
+
+	formatted = trans.FmtCurrency(ut.CurrencyAccounting, "USD", -1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: ($1,234.50)
+
+	formatted = trans.FmtCurrencyWhole(ut.CurrencyStandard, "USD", -1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: -$1,234
+
+	formatted = trans.FmtNumber(1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: 1,234.5
+
+	formatted = trans.FmtNumberWhole(1234.50)
+	fmt.Println(formatted)
+	// OUTPUT: 1,234
+}

BIN
logo.png


+ 19 - 19
number.go

@@ -149,14 +149,19 @@ func (n Number) FmtPercent(number float64) string {
 
 // parseFormat takes a format string and returns a numberFormat instance
 func (n Number) parseFormat(pattern string, includeDecimalDigits bool) *numberFormat {
-	// processed := false
-	// if includeDecimalDigits {
-	// 	_, processed = numberFormats[pattern]
-	// } else {
-	// 	_, processed = numberFormatsNoDecimals[pattern]
-	// }
-
-	// if !processed {
+
+	if includeDecimalDigits {
+
+		if format, exists := numberFormats[pattern]; exists {
+			return format
+		}
+
+	} else {
+		if format, exists := numberFormatsNoDecimals[pattern]; exists {
+			return format
+		}
+	}
+
 	format := new(numberFormat)
 	patterns := strings.Split(pattern, ";")
 
@@ -236,24 +241,19 @@ func (n Number) parseFormat(pattern string, includeDecimalDigits bool) *numberFo
 
 	if includeDecimalDigits {
 		numberFormats[pattern] = format
-	} else {
-		format.maxDecimalDigits = 0
-		format.minDecimalDigits = 0
-		numberFormatsNoDecimals[pattern] = format
+		return format
 	}
 
-	// }
-
-	if includeDecimalDigits {
-		return numberFormats[pattern]
-	}
-
-	return numberFormatsNoDecimals[pattern]
+	format.maxDecimalDigits = 0
+	format.minDecimalDigits = 0
+	numberFormatsNoDecimals[pattern] = format
+	return format
 }
 
 // formatNumber takes an arbitrary numberFormat and a number and applies that
 // format to that number, returning the resulting string
 func (n Number) formatNumber(format *numberFormat, number float64) string {
+
 	negative := number < 0
 
 	// apply the multiplier first - this is mainly used for percents

+ 2 - 2
translator.go

@@ -50,7 +50,7 @@ func (t *Translator) Add(rule PluralRule, group string, key string, text string)
 	}
 
 	if _, ok := t.translations[rule][key]; ok {
-		panic(fmt.Sprintf("Translation with key '%s' already exists", key))
+		panic(fmt.Sprintf("Translation with key %q already exists", key))
 	}
 
 	t.translations[rule][key] = trans
@@ -113,7 +113,7 @@ func (t *Translator) PSafe(key string, count interface{}, a ...interface{}) (str
 
 	trans, ok := t.translations[rule][key]
 	if !ok {
-		return "", errors.New("***** WARNING:***** Translation Key " + key + " Not Found")
+		return "", errors.New("***** WARNING:***** Translation Key '" + key + "' Not Found")
 	}
 
 	return fmt.Sprintf(trans.text, a...), nil