Skip to content

Commit 1c9e017

Browse files
mh-cbonnicksnyder
authored andcommitted
handle Count field from template data
1 parent 8efe6b8 commit 1c9e017

File tree

5 files changed

+98
-33
lines changed

5 files changed

+98
-33
lines changed

goi18n/doc.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,88 +6,88 @@
66
// Help documentation:
77
//
88
// goi18n manages translation files.
9-
//
9+
//
1010
// Usage:
11-
//
11+
//
1212
// goi18n merge Merge translation files
1313
// goi18n constants Generate constant file from translation file
14-
//
14+
//
1515
// For more details execute:
16-
//
16+
//
1717
// goi18n [command] -help
18-
//
18+
//
1919
// Merge translation files.
20-
//
20+
//
2121
// Usage:
22-
//
22+
//
2323
// goi18n merge [options] [files...]
24-
//
24+
//
2525
// Translation files:
26-
//
26+
//
2727
// A translation file contains the strings and translations for a single language.
28-
//
28+
//
2929
// Translation file names must have a suffix of a supported format (e.g. .json) and
3030
// contain a valid language tag as defined by RFC 5646 (e.g. en-us, fr, zh-hant, etc.).
31-
//
31+
//
3232
// For each language represented by at least one input translation file, goi18n will produce 2 output files:
33-
//
33+
//
3434
// xx-yy.all.format
3535
// This file contains all strings for the language (translated and untranslated).
3636
// Use this file when loading strings at runtime.
37-
//
37+
//
3838
// xx-yy.untranslated.format
3939
// This file contains the strings that have not been translated for this language.
4040
// The translations for the strings in this file will be extracted from the source language.
4141
// After they are translated, merge them back into xx-yy.all.format using goi18n.
42-
//
42+
//
4343
// Merging:
44-
//
44+
//
4545
// goi18n will merge multiple translation files for the same language.
4646
// Duplicate translations will be merged into the existing translation.
4747
// Non-empty fields in the duplicate translation will overwrite those fields in the existing translation.
4848
// Empty fields in the duplicate translation are ignored.
49-
//
49+
//
5050
// Adding a new language:
51-
//
51+
//
5252
// To produce translation files for a new language, create an empty translation file with the
5353
// appropriate name and pass it in to goi18n.
54-
//
54+
//
5555
// Options:
56-
//
56+
//
5757
// -sourceLanguage tag
5858
// goi18n uses the strings from this language to seed the translations for other languages.
5959
// Default: en-us
60-
//
60+
//
6161
// -outdir directory
6262
// goi18n writes the output translation files to this directory.
6363
// Default: .
64-
//
64+
//
6565
// -format format
6666
// goi18n encodes the output translation files in this format.
6767
// Supported formats: json, yaml
6868
// Default: json
69-
//
69+
//
7070
// Generate constant file from translation file.
71-
//
71+
//
7272
// Usage:
73-
//
73+
//
7474
// goi18n constants [options] [file]
75-
//
75+
//
7676
// Translation files:
77-
//
77+
//
7878
// A translation file contains the strings and translations for a single language.
79-
//
79+
//
8080
// Translation file names must have a suffix of a supported format (e.g. .json) and
8181
// contain a valid language tag as defined by RFC 5646 (e.g. en-us, fr, zh-hant, etc.).
82-
//
82+
//
8383
// Options:
84-
//
84+
//
8585
// -package name
8686
// goi18n generates the constant file under the package name.
8787
// Default: R
88-
//
88+
//
8989
// -outdir directory
9090
// goi18n writes the constant file to this directory.
9191
// Default: .
92-
//
92+
//
9393
package main

i18n/bundle/bundle.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ func (b *Bundle) translate(lang *language.Language, translationID string, args .
260260
dataMap["Count"] = count
261261
data = dataMap
262262
}
263+
} else {
264+
dataMap := toMap(data)
265+
if c, ok := dataMap["Count"]; ok {
266+
count = c
267+
}
263268
}
264269

265270
p, _ := lang.Plural(count)

i18n/bundle/bundle_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,26 @@ func BenchmarkTranslatePluralWithMap(b *testing.B) {
270270
}
271271
}
272272

273+
func BenchmarkTranslatePluralWithMapAndCountField(b *testing.B) {
274+
data := map[string]interface{}{
275+
"Person": "Bob",
276+
"Count": 26,
277+
}
278+
279+
translationTemplate := map[string]interface{}{
280+
"one": "{{.Person}} is {{.Count}} year old.",
281+
"other": "{{.Person}} is {{.Count}} years old.",
282+
}
283+
expected := "Bob is 26 years old."
284+
285+
tf := createBenchmarkTranslateFunc(b, translationTemplate, nil, expected)
286+
287+
b.ResetTimer()
288+
for i := 0; i < b.N; i++ {
289+
tf(data)
290+
}
291+
}
292+
273293
func BenchmarkTranslatePluralWithStruct(b *testing.B) {
274294
data := struct{ Person string }{Person: "Bob"}
275295
tf := createBenchmarkPluralTranslateFunc(b)

i18n/example_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ func Example() {
3030
fmt.Println(T("person_unread_email_count", 1, bobStruct))
3131
fmt.Println(T("person_unread_email_count", 2, bobStruct))
3232

33+
type Count struct{ Count int }
34+
fmt.Println(T("your_unread_email_count", Count{0}))
35+
fmt.Println(T("your_unread_email_count", Count{1}))
36+
fmt.Println(T("your_unread_email_count", Count{2}))
37+
38+
fmt.Println(T("your_unread_email_count", map[string]interface{}{"Count": 0}))
39+
fmt.Println(T("your_unread_email_count", map[string]interface{}{"Count": "1"}))
40+
fmt.Println(T("your_unread_email_count", map[string]interface{}{"Count": "3.14"}))
41+
3342
fmt.Println(T("person_unread_email_count_timeframe", 3, map[string]interface{}{
3443
"Person": "Bob",
3544
"Timeframe": T("d_days", 0),
@@ -43,6 +52,22 @@ func Example() {
4352
"Timeframe": T("d_days", 2),
4453
}))
4554

55+
fmt.Println(T("person_unread_email_count_timeframe", 1, map[string]interface{}{
56+
"Count": 30,
57+
"Person": "Bob",
58+
"Timeframe": T("d_days", 0),
59+
}))
60+
fmt.Println(T("person_unread_email_count_timeframe", 2, map[string]interface{}{
61+
"Count": 20,
62+
"Person": "Bob",
63+
"Timeframe": T("d_days", 1),
64+
}))
65+
fmt.Println(T("person_unread_email_count_timeframe", 3, map[string]interface{}{
66+
"Count": 10,
67+
"Person": "Bob",
68+
"Timeframe": T("d_days", 2),
69+
}))
70+
4671
// Output:
4772
// Hello world
4873
// Hello Bob
@@ -57,7 +82,16 @@ func Example() {
5782
// Bob has 0 unread emails.
5883
// Bob has 1 unread email.
5984
// Bob has 2 unread emails.
85+
// You have 0 unread emails.
86+
// You have 1 unread email.
87+
// You have 2 unread emails.
88+
// You have 0 unread emails.
89+
// You have 1 unread email.
90+
// You have 3.14 unread emails.
6091
// Bob has 3 unread emails in the past 0 days.
6192
// Bob has 3 unread emails in the past 1 day.
6293
// Bob has 3 unread emails in the past 2 days.
94+
// Bob has 1 unread email in the past 0 days.
95+
// Bob has 2 unread emails in the past 1 day.
96+
// Bob has 3 unread emails in the past 2 days.
6397
}

i18n/i18n.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,15 @@ import (
6969
// If translationID is a non-plural form, then the first variadic argument may be a map[string]interface{}
7070
// or struct that contains template data.
7171
//
72-
// If translationID is a plural form, then the first variadic argument must be an integer type
72+
// If translationID is a plural form, the function accepts two parameter signatures
73+
// 1. T(count int, data struct{})
74+
// The first variadic argument must be an integer type
7375
// (int, int8, int16, int32, int64) or a float formatted as a string (e.g. "123.45").
74-
// The second variadic argument may be a map[string]interface{} or struct that contains template data.
76+
// The second variadic argument may be a map[string]interface{} or struct{} that contains template data.
77+
// 2. T(data struct{})
78+
// data must be a struct{} or map[string]interface{} that contains a Count field and the template data,
79+
// Count field must be an integer type (int, int8, int16, int32, int64)
80+
// or a float formatted as a string (e.g. "123.45").
7581
type TranslateFunc func(translationID string, args ...interface{}) string
7682

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

0 commit comments

Comments
 (0)