rails i18n - 用里面的链接翻译文本

kik*_*ito 92 ruby-on-rails internationalization

我想要一个看起来像这样的文本:

已经注册?登录!

请注意,文本上有一个链接.在这个例子中它指向谷歌 - 实际上它将指向我的应用程序log_in_path.

我找到了两种方法,但没有一种看起来"正确".

我知道的第一种方法涉及到我的en.yml:

log_in_message: "Already signed up? <a href='{{url}}'>Log in!</a>"
Run Code Online (Sandbox Code Playgroud)

在我看来:

<p> <%= t('log_in_message', :url => login_path) %> </p>
Run Code Online (Sandbox Code Playgroud)

这是有效的,但是对我来说这<a href=...</a>部分en.yml并不是很干净.

我知道的另一个选择是使用本地化视图 - login.en.html.erblogin.es.html.erb.

这也感觉不对,因为唯一不同的是前面提到的那条线; 对于所有视图,将重复视图的其余部分(~30行).它不会很干.

我想我可以使用"局部部分",但这看起来太麻烦了; 我想我更喜欢第一个拥有这么多小视图文件的选项.

所以我的问题是:是否有一种"正确"的方式来实现这一点?

Sim*_*tti 171

en.yml

log_in_message_html: "This is a text, with a %{href} inside."
log_in_href: "link"
Run Code Online (Sandbox Code Playgroud)

login.html.erb

<p> <%= t("log_in_message_html", href: link_to(t("log_in_href"), login_path)) %> </p>
Run Code Online (Sandbox Code Playgroud)

  • 在Rails 3中,YAML转换字符串中的语法已更改为"%{href}".此外,由于输出会自动转义,您需要明确指定`raw`或`.html_safe`,或者使用`_html`后缀翻译键,如`login_message_html`,并且将自动跳过转义. (65认同)
  • 如果不是很明显(对于那些懒得检查编辑日志的人),上面的[回答](http://stackoverflow.com/a/2544107/766570)已被编辑为包含@ coreyward的评论. (15认同)
  • @Archonic那不是真的.`t('string')`与`t("string")`相同.他们是一回事. (3认同)
  • 得爱铁路使链接复杂化.应该看起来像这个`t('some.key',link:link_to()).html_safe` (3认同)
  • 如果你在链接文本中有多个单词,那么这样的翻译将产生奇怪的翻译.例如,"我们有一个惊人的<a href='x'>提供各种各样的东西</a>,你可以买.你把切碎的东西发给翻译,你很可能得到两个措辞,如"我们有一个惊人的<a href='x'>整套商品</a>,你可以用其他语言购买.最好找到一个不会将它们分开的解决方案. (2认同)
  • 我不知道为什么这有这么多票。这个问题(或者至少是这样的问题)的重点是将单个英语句子或表达式作为 i18n 数据中的一个单元,以便可以将其作为单个实体进行翻译。@trcarden 的评论暗示了这个问题。 (2认同)

hol*_*lli 11

在locale.yml文件中分隔文本和链接可以工作一段时间,但由于链接在单独的翻译项目中(如Simones的答案),因此难以翻译和维护这些文本.如果你开始有许多字符串/翻译与链接,你可以干一点.

我在application_helper.rb中做了一个帮助:

# Converts
# "string with __link__ in the middle." to
# "string with #{link_to('link', link_url, link_options)} in the middle."
def string_with_link(str, link_url, link_options = {})
  match = str.match(/__([^_]{2,30})__/)
  if !match.blank?
    raw($` + link_to($1, link_url, link_options) + $')
  else
    raise "string_with_link: No place for __link__ given in #{str}" if Rails.env.test?
    nil
  end
end
Run Code Online (Sandbox Code Playgroud)

在我的en.yml中:

log_in_message: "Already signed up? __Log in!__"
Run Code Online (Sandbox Code Playgroud)

在我看来:

<p><%= string_with_link(t('.log_in_message'), login_path) %></p>
Run Code Online (Sandbox Code Playgroud)

这样,转换消息更容易,因为链接文本在locale.yml文件中明确定义.

  • 好的解决方案 我将它放入Gem中,它允许您定义链接"这是一个%{link:link to Google}".它允许您在单个字符串中包含多个链接,处理XSS并允许嵌套转换.看看https://github.com/iGEL/i18n_link/ (5认同)

iGE*_*GEL 7

我拿了霍利斯解决方案并制作了一个叫它的宝石it.我们来看一个例子:

log_in_message: "Already signed up? %{login:Log in!}"
Run Code Online (Sandbox Code Playgroud)

然后

<p><%=t_link "log_in_message", :login => login_path %></p>
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅https://github.com/iGEL/it.


Emu*_*Emu 5

en.yml中

registration:
    terms:
      text: "I do agree with the terms and conditions: %{gtc} / %{stc}"
      gtc: "GTC"
      stc: "STC"
Run Code Online (Sandbox Code Playgroud)

de.yml

registration:
    terms:
      text: "Ich stimme den Geschäfts- und Nutzungsbedingungen zu: %{gtc} / %{stc}"
      gtc: "AGB"
      stc: "ANB"
Run Code Online (Sandbox Code Playgroud)

new.html.erb [假设]

<%= t(
   'registration.terms.text',
    gtc:  link_to(t('registration.terms.gtc'),  terms_and_conditions_home_index_url + "?tab=gtc"),
    stc: link_to(t('registration.terms.stc'), terms_and_conditions_home_index_url + "?tab=stc")
 ).html_safe %>
Run Code Online (Sandbox Code Playgroud)