Rails I18n,检查翻译是否存在?

83

我正在开发一个Rails 3应用程序,想要在输出翻译文本之前检查其是否存在,如果不存在,则回退到一些静态文本。我可以这样做:

if I18n.t("some_translation.key").to_s.index("translation missing")

但我觉得应该有比这更好的方法。如果Rails将来将“translation missing”更改为“translation not found”,或者由于某种奇怪的原因文本包含“translation missing”,有什么想法吗?

9个回答

145

根据你的描述,这应该可以工作:

I18n.t("some_translation.key", :default => "fallback text")

查看文档获取更多细节。


86

你也可以使用

I18n.exists?(key, locale)
I18n.exists?('do_i_exist', :en)

1
这实际上是能够工作的。但该方法并没有被记录下来,只是在此提及:http://www.rubydoc.info/github/svenfuchs/i18n/master/I18n/Backend/Base#exists%3F-instance_method - Cristian
1
I18n.exists?('key') seems like the core evaluation. I've used it in helper_methods for fallback actions if no key value is set, e.g. title = I18n.exists?('page_title.default') ? t('page_title.default') : "Fallback title..." - Robert Travis Pierce
https://rdoc.info/github/ruby-i18n/i18n/I18n/Base#exists%3F-instance_method - Alex
这是一个不错的解决方案,但如果您的项目中有 config.i18n.fallbacks,它将无法工作。我猜会导致不存在的键返回 true,因为它会回退到另一个语言环境,并在那里找到所请求的键。 - Tashows

36

:default并不总是解决方案。在更高级的情况下,请使用以下内容:

helpers/application.rb:

def i18n_set? key
  I18n.t key, :raise => true rescue false
end

任何 ERB 模板:
<% if i18n_set? "home.#{name}.quote" %>
  <div class="quote">
    <blockquote><%= t "home.#{name}.quote" %></blockquote>
    <cite><%= t "home.#{name}.cite" %></cite>
  </div>
<% end %>

21

这个怎么样?

I18n.t('some_translation.key', :default => '').empty?

我只是觉得这样感觉更好,更像是没有翻译

注意:如果你故意将翻译值设为空字符串,则此方法无效。


12

使用 :default 参数:

I18n.t("some_translation.key", :default => 'some text')

4
有时候翻译失败后,你可能需要做更多的事情。
v = "doesnt_exist"
begin
  puts I18n.t "langs.#{v}", raise: true
rescue
  ...
  puts "Nooo #{v} has no Translation!"
end

2

Rails 4

我正在遍历一些陪审员的网址。最大的url数量为2,default_lang为“de”。这是我使用的yaml:

de:
 jury:
  urls:
   url0: http://www.example.com
   name0: example.com
   url1:
   name1:

en:
 jury:
  urls:
   url0: 
   name0: 
   url1:
   name1:

以下是我检查URL是否存在以及如果该URL不存在于其他语言中时如何回退到I18n默认语言“de”的方法。我使用了@albandiguer的答案,这个方法非常好用。

希望这能帮助到某些人:

    <% 2.times do |j| %>
        <% if I18n.exists?("jury.urls.url#{j}", "de") &&
           I18n.exists?("jury.urls.name#{j}", "de") %>
          <%= "<br/>".html_safe  if j == 1%>
          <a href="<%= t("jury.urls.url#{j}") %>" target="_blank">
            <%= t("jury.urls.name#{j}") %>
          </a>
        <% end %>
     <% end %>

2

这是一个技巧,但我认为有时可能会有用...

假设您在i18n文件中有以下内容:

en:
  key:
    special_value: "Special value"
    default_value: "Default value"

您可以这样做:

if I18n.t('key').keys.include?(:special_value)
  I18n.t('key.special_value')
else
  I18n.t('key.default_value')
end
# => "Special value"

if I18n.t('key').keys.include?(:unknown_value)
  I18n.t('key.special_value')
else
  I18n.t('key.default_value')
end
# => "Default value"

注意:只有在测试非根键时才能使用此方法,因为您正在查看父项。

实际上,有趣的是当请求父键时您可以得到什么...

I18n.t('key')
# => {:special_value=>"Special value", :default_value=>"Default value"}

一行代码:I18n.t('key.special_value', default: I18n.t('key.default_value')) - andoke

0

几个版本之前,有一种更简单的方法i18next文档 > API > t

您可以将一个键指定为字符串或多个键作为字符串数组。将返回解析的第一个键。

例如:

i18next.t ( ['unknown.key', 'my.key' ] ); // 将返回'my.key'的值

此外,您还可以使用上下文t如果在上下文中未找到,则返回默认值。


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