Skip to content

国际化

govalid 全链路 locale 感知:规则消息、字段 label 与诊断模板都可 本地化。

内置 locale

LocaleTag
中文(默认)language.Chinese
英文language.English

默认 locale 是中文。govalid.defaultTemplateLanguage 导出—— 请按调用粒度选择 locale。

按调用 locale

Check 接受可选的 language.Tag

go
import "golang.org/x/text/language"

errs, ok := govalid.Check(form, language.English)

选择规则:

  1. 如果请求的 locale 已注册,使用其模板集合。
  2. 如果该 locale 未注册,回退到包默认值(中文)。
  3. 如果在选定 locale 内某个具体的模板键缺失,回退到 _unknownErrorTemplate

本地化字段 label

label-<lang> 标签让你在默认 label 旁附加按 locale 的 label。 lang 后缀对应 language.Tag.String()

go
type Form struct {
    Email string `valid:"required" label:"邮箱" label-en:"Email"`
}

govalid.Check(form, language.English) // → "Email can not be empty"
govalid.Check(form, language.Chinese) // → "邮箱不能为空"

每次调用的查找顺序:

  1. 请求 locale 对应的 label-<lang>
  2. label
  3. Go 字段名

添加一个新 locale

SetMessageTemplates 会在首次使用时创建该 locale:

go
import "golang.org/x/text/language"

govalid.SetMessageTemplates(map[string]string{
    "required": " は必須です",
    "min":      " は %v 以上である必要があります",
}, language.Japanese)

你可以选择性地覆盖条目——只有你提供的键会被替换,剩下的按上面的 fallback 规则使用默认 locale。

运行时选择 locale

常见做法是从 HTTP 请求推导 locale:

go
func handler(w http.ResponseWriter, r *http.Request) {
    var form Form
    _ = json.NewDecoder(r.Body).Decode(&form)

    matcher := language.NewMatcher([]language.Tag{
        language.Chinese, language.English, language.Japanese,
    })
    accept, _, _ := language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
    tag, _, _ := matcher.Match(accept...)

    errs, ok := govalid.Check(form, tag)
    if !ok {
        // 把 errs 渲染给客户端
    }
}

按 locale 的诊断模板

5 个 _ 前缀的诊断模板也支持本地化。覆盖方式和普通规则模板一致:

go
govalid.SetMessageTemplates(map[string]string{
    "_checkerNotFound":      "Unknown rule",
    "_paramError":           "Bad rule parameters",
    "_valueTypeError":       "Wrong field type",
    "_fieldNotFound":        "Referenced field not found",
    "_unknownErrorTemplate": "Validation failed",
}, language.English)

基于 MIT 协议发布。