Rails I18n嵌套翻译键

时间:2011-07-22 17:42:47

标签: ruby-on-rails ruby internationalization

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

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')

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:0)

你可以做" 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]!'