You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gobuffalo模型中使用i18n翻译器?

在Gobuffalo模型中访问i18n翻译器的解决方案

这个问题我之前也碰到过,确实模型里直接调用i18n翻译器不像actions里那么顺手——毕竟模型本身不持有buffalo.Context。给你几个实用的方案:


方案一:直接传递翻译器/上下文到模型方法

这是最直接也最安全的方式,因为请求级的上下文/翻译器不会有并发问题。

方式1:传递*i18n.Translator实例

在模型里定义方法时,把翻译器作为参数传入:

// models/user.go
type User struct {
  gorm.Model
  Name string
}

// 示例方法:需要翻译内容时接收翻译器参数
func (u *User) GetWelcomeMessage(t *i18n.Translator) string {
  return t.Translate("user.welcome", map[string]interface{}{
    "Name": u.Name,
  })
}

然后在actions里调用时,把当前请求的翻译器传进去:

// actions/users.go
func ShowUser(c buffalo.Context) error {
  t := c.Value("translator").(*i18n.Translator)
  user := &User{}
  if err := DB.First(user, c.Param("id")).Error; err != nil {
    return c.Error(http.StatusNotFound, err)
  }
  welcomeMsg := user.GetWelcomeMessage(t)
  c.Set("welcome_msg", welcomeMsg)
  return c.Render(http.StatusOK, r.HTML("users/show.plush.html"))
}

方式2:直接传递buffalo.Context

如果模型方法需要用到上下文的其他能力(不止翻译),可以直接传上下文进去:

func (u *User) GetWelcomeMessage(c buffalo.Context) string {
  t := c.Value("translator").(*i18n.Translator)
  return t.Translate("user.welcome", map[string]interface{}{
    "Name": u.Name,
  })
}

调用时直接传c即可:

welcomeMsg := user.GetWelcomeMessage(c)

方案二:针对模型验证场景的优化

如果是在模型验证时需要翻译错误消息(比如用github.com/gobuffalo/validate/v3),可以封装带翻译器的验证函数:

// models/user.go
func ValidateUserWithTranslator(user *User, t *i18n.Translator) error {
  v := validate.New()
  
  if user.Name == "" {
    v.AddError("name", t.Translate("user.name.required"))
  }
  if len(user.Password) < 6 {
    v.AddError("password", t.Translate("user.password.min_length"))
  }
  
  return v.Error()
}

在actions里调用这个验证函数,传入当前翻译器:

// actions/users.go
func CreateUser(c buffalo.Context) error {
  t := c.Value("translator").(*i18n.Translator)
  user := &User{}
  if err := c.Bind(user); err != nil {
    return err
  }
  if err := ValidateUserWithTranslator(user, t); err != nil {
    c.Set("errors", err.(validate.Errors))
    return c.Render(http.StatusUnprocessableEntity, r.HTML("users/new.plush.html"))
  }
  DB.Create(user)
  return c.Redirect(http.StatusSeeOther, "/users/%d", user.ID)
}

方案三:全局注入(谨慎使用)

如果你的应用是单语言场景,且不需要动态切换语言,可以考虑把翻译器设为全局变量。但多语言应用绝对不要用这个方式——会出现并发请求的语言混乱问题。

示例代码:

// models/translator.go
var GlobalTranslator *i18n.Translator

// 在应用启动时初始化全局翻译器
func init() {
  var err error
  GlobalTranslator, err = i18n.New(&i18n.Options{
    DefaultLanguage: "en",
    Translations:   i18n.Translations{
      // 加载翻译文件逻辑
    },
  })
  if err != nil {
    panic(err)
  }
}

然后在模型里直接调用:

func (u *User) GetWelcomeMessage() string {
  return GlobalTranslator.Translate("user.welcome", map[string]interface{}{
    "Name": u.Name,
  })
}

总结

最推荐的是方案一,它完全符合Gobuffalo的请求上下文设计,既安全又灵活,不会引入额外的并发风险。

内容的提问来源于stack exchange,提问作者emurmotol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:02:59