覆盖Rails翻译帮助程序

8
我希望使用I18n.translate()I18n.t()来指定一个特定的语言环境,而不是使用I18n.locale
我不想每次都使用I18n.t(:my_key, locale: :my_locale),所以如果能覆盖函数本身就好了。
我试图把它放在一个新的helper中:
# my_helper.rb
module MyHelper
  def translate(key, options = {})
    options[:locale] = MY_LOCALE
    I18n.translate key, options
  end
  alias :t :translate
end

这对于像t('word')这样的“硬编码”很有效,但对于像t('.title')这样的“动态编码”,它无法找到正确的路径,应该使用我的部分的路径,即de.users.form.title
感谢任何帮助!

我认为你漏掉了 I18n.with_locale 方法。 - phoet
谢谢你的评论。I18n.with_locale(MY_LOCALE){}I18n.t(:key, locale: MY_LOCALE)是相同的。我希望使用标准的 I18n.t() 函数并且集中定义我想要使用的本地化语言来解决问题。 - Railsana
你不能只是从参数、域或类似的地方设置区域设置吗?就像这里讨论的那样:http://guides.rubyonrails.org/i18n.html#setting-and-passing-the-locale。这样,您将为每个请求设置区域设置,然后可以像平常一样使用`I18n.t`,但使用为请求设置的区域设置而不是默认区域设置。 - Frost
嘿,Frost,感谢你的回答。我想在数据库更新时使用特定的I18n.locale,但在用户界面中使用另一种语言。例如:一个拥有德语用户界面的德国用户应该使用法语内容和法语标识符进行编辑。 - Railsana
2个回答

9

看起来有些混淆的是:

I18n.translate不执行“lazy lookups”(即如果以点开头,则将查找键限定为当前部分)您所期望的功能。这是ActionView::Helpers::TranslationHelper#translate的一个特性,以及其他一些特性

您的方法正在覆盖ActionView::Helpers::TranslationHelper#translate,而没有调用super来获取延迟加载。因此,如果您想坚持覆盖该方法,我认为您可能需要:

# my_helper.rb
module MyHelper
  def translate(key, options = {})
    # If you don't want to ignore options[:locale] if it's passed in,
    # change to options[:locale] ||= MY_LOCALE
    options[:locale] = MY_LOCALE 
    super(key, options)
  end
  alias :t :translate
end

个人而言,我更愿意在视图中每次使用 t(:my_key, locale: :my_locale) 而不进行覆盖,或者最多只是有一个包装调用 ActionView::Helpers::TranslationHelper#translate 的单独辅助方法,并带有额外的业务逻辑来强制使用特定的语言环境。

1
您可以尝试以下操作:

config/initializers/i18n.rb

module I18n
  def german(*args)
    options = args.last.is_a?(Hash) ? args.pop.dup : {}
    args << options.merge(locale: :de)
    translate(*args)
  end
  module_function :german
end

如果你需要定义多个模块函数,使用下面这种方式会比每次使用module_function更容易:

module I18n
  extend(Module.new do
    def german
      ...
    end

    def english
      ...
    end

    def japaneese
      ...
    end
  end)
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接