-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from go-seatbelt/i18n/add-simple-i18n-funcs
i18n: add basic i18n support
- Loading branch information
Showing
12 changed files
with
237 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
.DS_Store | ||
|
||
master.key | ||
NOTES.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"Home": { | ||
"other": "Home" | ||
}, | ||
"Hello": { | ||
"other": "Hello" | ||
}, | ||
"WelcomeMessage": { | ||
"other": "Welcome to Seatbelt. This is a sample application that shows off all the framework can do." | ||
}, | ||
"SessionData": { | ||
"other": "Set and view session data" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"Home": { | ||
"other": "Maison" | ||
}, | ||
"Hello": { | ||
"other": "Salut" | ||
}, | ||
"WelcomeMessage": { | ||
"other": "Bienvenue à Seatbelt. Voici un application qui démontre tout que le framework peut faire." | ||
}, | ||
"SessionData": { | ||
"other": "Voire et définir les données de session" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
{{ define "title-index" }}Home{{ end }} | ||
<h1 class="title">Hello!</h1> | ||
<p>Welcome to Seatbelt. This is a sample application that shows off all the framework can do.</p> | ||
<a href="/session">Set and view session data</a> | ||
{{ define "title-index" }}{{ t "Home" . }}{{ end }} | ||
<h1 class="title">{{ t "Hello" . }}</h1> | ||
<p>{{ t "WelcomeMessage" . }}</p> | ||
<a href="/session">{{ t "SessionData" . }}</a> | ||
<a href="/txt">Plaintext link</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package i18n | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/nicksnyder/go-i18n/v2/i18n" | ||
"golang.org/x/text/language" | ||
) | ||
|
||
type Translator struct { | ||
path string | ||
bundle *i18n.Bundle | ||
} | ||
|
||
// New creates a new instance of a translator from the given file path. | ||
func New(path string) *Translator { | ||
bundle := i18n.NewBundle(language.English) | ||
bundle.RegisterUnmarshalFunc("json", json.Unmarshal) | ||
|
||
// If the path is an empty string, we'll fall back to the default bundle, | ||
// which will output the "translation missing" error for every string. | ||
// Otherwise, load the translation data from the given filepath. | ||
if path != "" { | ||
if err := filepath.Walk(path, func(filepath string, info os.FileInfo, _ error) error { | ||
if info == nil || info.IsDir() { | ||
return nil | ||
} | ||
// TODO Check file extension (or possibly regex of filename) so | ||
// that it doesn't break on unintenionally added files. | ||
_, err := bundle.LoadMessageFile(filepath) | ||
return err | ||
}); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
return &Translator{ | ||
path: path, | ||
bundle: bundle, | ||
} | ||
} | ||
|
||
// T translates the string with the given name. | ||
func (t *Translator) T(r *http.Request, id string, data map[string]interface{}, pluralCount ...int) string { | ||
lang := r.URL.Query().Get("locale") | ||
accept := r.Header.Get("Accept-Language") | ||
|
||
localizer := i18n.NewLocalizer(t.bundle, lang, accept) | ||
|
||
lc := &i18n.LocalizeConfig{ | ||
MessageID: id, | ||
TemplateData: data, | ||
} | ||
for _, pc := range pluralCount { | ||
lc.PluralCount = pc | ||
} | ||
|
||
text, err := localizer.Localize(lc) | ||
if err != nil { | ||
// TODO Consider a "development" switch for this to raise an error or | ||
// something rather than outputting the "translation missing:" | ||
// message. | ||
return "translation missing: " + guessLang(accept, lang) + ", " + id | ||
} | ||
|
||
return text | ||
} | ||
|
||
// TODO Make this work the exact same as i18n.NewLocalizer | ||
func guessLang(langs ...string) string { | ||
defaultLang := language.English.String() | ||
|
||
if len(langs) == 0 { | ||
return defaultLang | ||
} | ||
|
||
var guessedLang string | ||
for i := len(langs) - 1; i != 0; i-- { | ||
if langs[i] == "" { | ||
continue | ||
} | ||
|
||
tag, err := language.Parse(langs[i]) | ||
if err != nil { | ||
continue | ||
} | ||
guessedLang = tag.String() | ||
} | ||
|
||
if guessedLang == "" { | ||
return defaultLang | ||
} | ||
return guessedLang | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package i18n | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
) | ||
|
||
func TestTranslator(t *testing.T) { | ||
translator := New("testdata") | ||
|
||
req := httptest.NewRequest(http.MethodGet, "/?locale=fr", nil) | ||
|
||
s := translator.T(req, "PersonCats", map[string]interface{}{ | ||
"Name": "Ben", | ||
"Count": 0, | ||
}) | ||
|
||
expected := "Ben a 0 chats." | ||
if expected != s { | ||
t.Fatalf("expected %s but got %s", expected, s) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"PersonCats": { | ||
"one": "{{.Name}} has {{.Count}} cat.", | ||
"other": "{{.Name}} has {{.Count}} cats." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"PersonCats": { | ||
"one": "{{.Name}} a {{.Count}} chat.", | ||
"other": "{{.Name}} a {{.Count}} chats." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters