【问题标题】:Rails I18n nested translation keysRails I18n 嵌套翻译键
【发布时间】:2011-10-11 06:12:23
【问题描述】:

有没有办法嵌套翻译查找?像这样的:

en:
  uh_oh: 'Uh Oh!'
  error1: :'uh_oh' + ' There was a big error!'
  error2: :'uh_oh' + ' There was another big error!'
I18n.t('error1') #=> 'Uh Oh! There was a big error!'
I18n.t('error2') #=> 'Uh Oh! There was another big error!'

我已经尝试了很多变体,还尝试使用 Ruby 翻译文件而不是 YAML。请注意,这确实有效:

en:
  uh_oh: 'Uh Oh!'
  error1: :'uh_oh'
I18n.t('error1') #=> 'Uh Oh!'

但如果我向error1 添加额外的文本,uh_oh 不会被翻译。

基本上我想避免总是用通用术语传递,例如:

en:
  uh_oh: 'Uh Oh!'
  error1: '%{uh_oh} There was a big error!'
I18n.t('error1', {uh_oh: I18n.t('uh_oh')})

对于像uh_oh 这样的常用术语,每次调用error1(以及使用uh_oh 的任何其他键)的插值都是相同的,因此必须传入字符串实际上没有意义被插值。改为执行以下操作会更容易,并让 error1 翻译负责公共密钥翻译:

I18n.t('error1')

【问题讨论】:

    标签: ruby-on-rails ruby internationalization


    【解决方案1】:

    我不会回答您的问题(我认为 i18n gem 不可能,但可能是错误的)。我要说的是,您不应该采用这种方法并给您链接 [1] 作为背景。作为开发人员,很自然地会看到模式并提取通用代码以保持干燥。在处理多种语言时,这一步太过分了,因为它会妨碍正确的翻译。并非所有语言都遵循与英语相同的句子结构,并且您要替换的内容可能需要更改以与句子的其余部分一致。

    在我工作的一个网站上,我们遇到了法语问题。我们有包含位置名称的句子,这在英语中很简单。 “%{location_name} 属性”适用于任何位置名称。然而,在法语中,您需要不同的结构,具体取决于位置是城镇、省、地区,以及名称是否以元音开头。

    [1]http://www.multilingual.com/articleDetail.php?id=594

    【讨论】:

    • 我知道你对不同句子结构和语法规则的意思。但是从翻译键/值对(就像我问的那样)或通过显式传递它来获取变量的值并不会改变您在每种语言的文件中构造句子的方式。
    • 没错,不过你仍然需要注意性别。我认为您需要为此编写自己的助手。即使您的密钥类似于:key: "!some.key! foo bar" 您的 I18n.t 包装器将在哪里获取密钥,然后查找 some.key 并将其替换。
    • 您也可以将其用作自定义 i18n 后端。
    【解决方案2】:

    您可以自行执行“I18n.t('error1')”替换的原因是因为这是 I18n 称为“符号链接”的特殊情况。

    不幸的是,它只会做一个完整的替换。

    我看到解决此问题的两种解决方案。第一个是对 I18n 的输出进行后处理,当您无法完全控制何时调用 I18n 并且翻译消息的消耗可能会分散(例如在 Rails 中)时,这可能会很困难。最好的选择可能是覆盖 I18n.t 函数。

    另一个选择是利用在 I18n 后端存储 lambda 的能力。不幸的是,这意味着您不能将组合翻译存储在 YAML 文件中,因为它只支持基本字符串。

    例如,在 YAML 翻译中,我们可能会有任何错误消息:

    en:
      error:  "There was a big error [%{arg}]!"
    

    现在我们想在它之前加上 uh_oh 的翻译来调用它。 我们需要将 uh_oh 的组合翻译存储到 I18n 后端:

    translam = lambda { |key,opts| "Uh Oh! #{I18n.t(opts[:for],opts)}" }
    I18n.backend.store_translations(:en,:uh_oh => translam)
    

    现在我们可以翻译“uh_oh”并给它我们想要翻译的错误以及它可能需要的任何参数:

    I18n.t(:uh_oh, for: :error, arg: 42))  #=> 'Uh Oh! There was a big error [42]!'
    

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 1970-01-01
      • 2013-05-26
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-25
      相关资源
      最近更新 更多