Read in: English | 中文
Localized messages for protovalidate rule IDs. Use with go-i18n and template placeholders such as {{.Value}}.
go get github.com/jzero-io/protovalidate-translator/translatorUse the built-in embedded locales (en + zh):
import "github.com/jzero-io/protovalidate-translator/translator"
msg, _ := translator.TranslateDefault("zh", "float.lt", map[string]any{"Value": 100})
// msg == "值必须小于 100"
msgTW,_ := translator.TranslateDefault("zh-TW", "float.lt", map[string]any{"Value": 100})
// msg == "值必須小於 100"
msgEn, _ := translator.TranslateDefault("en", "float.lt", map[string]any{"Value": 100})
// msgEn == "value must be less than 100"Run the example:
go run ./examples/translate/main.goIt prints sample translations for a few rule IDs in English and Chinese.
After validating with protovalidate, use the violation’s rule ID and value to get a localized message:
err := validator.Validate(msg)
var valErr *protovalidate.ValidationError
if errors.As(err, &valErr) {
for _, v := range valErr.Violations {
ruleID := v.Proto.GetRuleId()
data := map[string]any{"Value": v.RuleValue.Interface()}
message, _ := translator.TranslateDefault("zh", ruleID, data)
// message is the localized error string
}
}Load your own locale directory (go-i18n JSON):
bundle, err := translator.LoadBundleFromDir("./locales")
msg, _ := translator.Translate(bundle, "zh", "en", "float.lt", map[string]any{"Value": 100})Or from an embedded FS:
//go:embed locales/*.json
var locales embed.FS
bundle, _ := translator.LoadBundleFromFS(locales, "locales")
msg, _ := translator.Translate(bundle, "zh", "en", "float.lt", data)You can add locales or single messages to the default bundle (used by TranslateDefault). Register before the first call to DefaultBundle or TranslateDefault.
Add a locale file from disk:
translator.AddDefaultLocaleFile("./locales/custom.json")
msg, _ := translator.TranslateDefault("zh", "float.lt", data)Add a locale file from an fs.FS (e.g. embed):
//go:embed custom.json
var customFS embed.FS
translator.AddDefaultLocaleFromFS(customFS, "custom.json")Add a single message (overrides or adds for that language):
translator.AddDefaultMessage("zh", "my.rule", "自訂:{{.Value}}")
msg, _ := translator.TranslateDefault("zh", "my.rule", map[string]any{"Value": 1})For full control, use a customizer:
translator.AddDefaultBundleCustomizer(func(b *i18n.Bundle) error {
// e.g. b.LoadMessageFile(path), b.AddMessages(tag, msgs...)
return nil
})- en (default) – English
- zh – 简体中文
- zh-TW – 繁體中文
Message IDs follow the rule IDs from buf/validate (e.g. float.lt, string.min_len, int32.gt). Add more languages by placing go-i18n JSON files in translator/locales/ and rebuilding, or by loading your own bundle.
- Main module (repo root): Contains only the importable
translatorpackage, with no tests and no dependency on generated pb files.go build ./...andgo mod tidywork out of the box. - Tests and examples live under
examples/, which has its owngo.modso the main module never references generated pb code.
make test # Main module: build only
cd examples && make proto-go && go test ./... -v # Generate pb and run all tests
# or from repo root:
make test-examples # Same as above
make extract # Regenerate en.json from validate.protoFrom the examples directory, run go mod tidy and go test ./... as needed. Integration tests require examples/translate/testdata/pb; run make proto-go in examples first.