Skip to content

Commit

Permalink
handle Count field from template data
Browse files Browse the repository at this point in the history
  • Loading branch information
mh-cbon authored and nicksnyder committed Oct 19, 2016
1 parent 8efe6b8 commit 1c9e017
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 33 deletions.
62 changes: 31 additions & 31 deletions goi18n/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,88 +6,88 @@
// Help documentation:
//
// goi18n manages translation files.
//
//
// Usage:
//
//
// goi18n merge Merge translation files
// goi18n constants Generate constant file from translation file
//
//
// For more details execute:
//
//
// goi18n [command] -help
//
//
// Merge translation files.
//
//
// Usage:
//
//
// goi18n merge [options] [files...]
//
//
// Translation files:
//
//
// A translation file contains the strings and translations for a single language.
//
//
// Translation file names must have a suffix of a supported format (e.g. .json) and
// contain a valid language tag as defined by RFC 5646 (e.g. en-us, fr, zh-hant, etc.).
//
//
// For each language represented by at least one input translation file, goi18n will produce 2 output files:
//
//
// xx-yy.all.format
// This file contains all strings for the language (translated and untranslated).
// Use this file when loading strings at runtime.
//
//
// xx-yy.untranslated.format
// This file contains the strings that have not been translated for this language.
// The translations for the strings in this file will be extracted from the source language.
// After they are translated, merge them back into xx-yy.all.format using goi18n.
//
//
// Merging:
//
//
// goi18n will merge multiple translation files for the same language.
// Duplicate translations will be merged into the existing translation.
// Non-empty fields in the duplicate translation will overwrite those fields in the existing translation.
// Empty fields in the duplicate translation are ignored.
//
//
// Adding a new language:
//
//
// To produce translation files for a new language, create an empty translation file with the
// appropriate name and pass it in to goi18n.
//
//
// Options:
//
//
// -sourceLanguage tag
// goi18n uses the strings from this language to seed the translations for other languages.
// Default: en-us
//
//
// -outdir directory
// goi18n writes the output translation files to this directory.
// Default: .
//
//
// -format format
// goi18n encodes the output translation files in this format.
// Supported formats: json, yaml
// Default: json
//
//
// Generate constant file from translation file.
//
//
// Usage:
//
//
// goi18n constants [options] [file]
//
//
// Translation files:
//
//
// A translation file contains the strings and translations for a single language.
//
//
// Translation file names must have a suffix of a supported format (e.g. .json) and
// contain a valid language tag as defined by RFC 5646 (e.g. en-us, fr, zh-hant, etc.).
//
//
// Options:
//
//
// -package name
// goi18n generates the constant file under the package name.
// Default: R
//
//
// -outdir directory
// goi18n writes the constant file to this directory.
// Default: .
//
//
package main
5 changes: 5 additions & 0 deletions i18n/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ func (b *Bundle) translate(lang *language.Language, translationID string, args .
dataMap["Count"] = count
data = dataMap
}
} else {
dataMap := toMap(data)
if c, ok := dataMap["Count"]; ok {
count = c
}
}

p, _ := lang.Plural(count)
Expand Down
20 changes: 20 additions & 0 deletions i18n/bundle/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,26 @@ func BenchmarkTranslatePluralWithMap(b *testing.B) {
}
}

func BenchmarkTranslatePluralWithMapAndCountField(b *testing.B) {
data := map[string]interface{}{
"Person": "Bob",
"Count": 26,
}

translationTemplate := map[string]interface{}{
"one": "{{.Person}} is {{.Count}} year old.",
"other": "{{.Person}} is {{.Count}} years old.",
}
expected := "Bob is 26 years old."

tf := createBenchmarkTranslateFunc(b, translationTemplate, nil, expected)

b.ResetTimer()
for i := 0; i < b.N; i++ {
tf(data)
}
}

func BenchmarkTranslatePluralWithStruct(b *testing.B) {
data := struct{ Person string }{Person: "Bob"}
tf := createBenchmarkPluralTranslateFunc(b)
Expand Down
34 changes: 34 additions & 0 deletions i18n/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ func Example() {
fmt.Println(T("person_unread_email_count", 1, bobStruct))
fmt.Println(T("person_unread_email_count", 2, bobStruct))

type Count struct{ Count int }
fmt.Println(T("your_unread_email_count", Count{0}))
fmt.Println(T("your_unread_email_count", Count{1}))
fmt.Println(T("your_unread_email_count", Count{2}))

fmt.Println(T("your_unread_email_count", map[string]interface{}{"Count": 0}))
fmt.Println(T("your_unread_email_count", map[string]interface{}{"Count": "1"}))
fmt.Println(T("your_unread_email_count", map[string]interface{}{"Count": "3.14"}))

fmt.Println(T("person_unread_email_count_timeframe", 3, map[string]interface{}{
"Person": "Bob",
"Timeframe": T("d_days", 0),
Expand All @@ -43,6 +52,22 @@ func Example() {
"Timeframe": T("d_days", 2),
}))

fmt.Println(T("person_unread_email_count_timeframe", 1, map[string]interface{}{
"Count": 30,
"Person": "Bob",
"Timeframe": T("d_days", 0),
}))
fmt.Println(T("person_unread_email_count_timeframe", 2, map[string]interface{}{
"Count": 20,
"Person": "Bob",
"Timeframe": T("d_days", 1),
}))
fmt.Println(T("person_unread_email_count_timeframe", 3, map[string]interface{}{
"Count": 10,
"Person": "Bob",
"Timeframe": T("d_days", 2),
}))

// Output:
// Hello world
// Hello Bob
Expand All @@ -57,7 +82,16 @@ func Example() {
// Bob has 0 unread emails.
// Bob has 1 unread email.
// Bob has 2 unread emails.
// You have 0 unread emails.
// You have 1 unread email.
// You have 2 unread emails.
// You have 0 unread emails.
// You have 1 unread email.
// You have 3.14 unread emails.
// Bob has 3 unread emails in the past 0 days.
// Bob has 3 unread emails in the past 1 day.
// Bob has 3 unread emails in the past 2 days.
// Bob has 1 unread email in the past 0 days.
// Bob has 2 unread emails in the past 1 day.
// Bob has 3 unread emails in the past 2 days.
}
10 changes: 8 additions & 2 deletions i18n/i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,15 @@ import (
// If translationID is a non-plural form, then the first variadic argument may be a map[string]interface{}
// or struct that contains template data.
//
// If translationID is a plural form, then the first variadic argument must be an integer type
// If translationID is a plural form, the function accepts two parameter signatures
// 1. T(count int, data struct{})
// The first variadic argument must be an integer type
// (int, int8, int16, int32, int64) or a float formatted as a string (e.g. "123.45").
// The second variadic argument may be a map[string]interface{} or struct that contains template data.
// The second variadic argument may be a map[string]interface{} or struct{} that contains template data.
// 2. T(data struct{})
// data must be a struct{} or map[string]interface{} that contains a Count field and the template data,
// Count field must be an integer type (int, int8, int16, int32, int64)
// or a float formatted as a string (e.g. "123.45").
type TranslateFunc func(translationID string, args ...interface{}) string

// IdentityTfunc returns a TranslateFunc that always returns the translationID passed to it.
Expand Down

0 comments on commit 1c9e017

Please sign in to comment.