3

下面的代码是我在 rails 应用程序中的一个咖啡脚本文件中的代码。我正在努力为“Select Account First”和“Select One”等字符串值添加 i18n 支持。在常规 javascript 文件中,我一直在使用 I18n.t("shared.select_account_first") 之类的东西来获取使用 i18n-js gem 的字符串的国际化值。

jQuery ->
  networks = $('#account_offering_network_id').html()
  select_network_options = new Option("Select Account First", "", true, false)

  filter_networks_by_account = (account) ->
    if account is 'Select One'
      $('#account_offering_network_id').html(select_network_options)
    else
      escaped_account = account.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1')
      options = $(networks).filter("optgroup[label='#{escaped_account}']")
      $('#account_offering_network_id').html(options.html())

  # Show proper network dropdown first time
  filter_networks_by_account($('#account_offering_account_id :selected').text())

  # Show proper network dropdown on account change
  $('#account_offering_account_id').change -> filter_networks_by_account($('#account_offering_account_id :selected').text())

所有这些的目标是根据所选帐户过滤网络下拉列表。如果未选择帐户(帐户下拉菜单的值显示“选择一个”或相应的 i18n 值),网络下拉菜单应在所选区域设置中显示“首先选择帐户”。

我正在使用 i18s-js gem(https://github.com/fnando/i18n-js) 在 javascript 中启用翻译。以下是我必须在应用程序中进行的更改以支持 gem。

在 application.js 中:

//= require i18n
//= require i18n/translations

在 production.rb 和 development.rb 中添加的属性:

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
config.i18n.available_locales = [:en, :ru]

在 application.html.erb 中:

<%# For localization/i18n in javascript %>
<script type="text/javascript">
  I18n.defaultLocale = "<%= I18n.default_locale %>";
  I18n.locale = "<%= I18n.locale %>";
  I18n.fallbacks = true;
</script>

最后我运行了“rake i18n:js:export”,它将创建一个翻译文件 (app/javascripts/i18n/translations.js),其中加载了名称-值对。现在,我可以通过任何 javascript 访问使用 I18n.t(name) 的翻译。

4

3 回答 3

0

我试图做同样的事情,但我认为你做不到,因为显然制作咖啡脚本的人做出了设计决定,禁止将 ruby​​ 变量注入到咖啡脚本文件中,以避免在每个请求上重新编译咖啡脚本 -如果你问我,有点无赖!一种可怕的方法是通过内联所需的翻译,但这听起来很可怕!

看看这个:How to access instance variables in CoffeeScript engine inside a Slim template

希望这可以帮助!

于 2013-06-01T11:01:00.307 回答
0

@mulus 的建议很有意义,因为您想缩小 js 并缓存它;做 a.js.erb不是最佳方式。

无论如何,这是一种快速简便的方法:

我正在使用 Ruby on Rails,所以在我的应用程序布局 ( app/views/layouts/application.html.erb) 中,我有以下内容:

<head>
  ...
  <meta name='locale' content="<%= params[:locale] %>"><meta>
  ...
</head>

这将允许我在“运行时”将语言环境从 Ruby on Rails 传递给 Javascript。

然后我创建了一个 Translator.coffee 文件

class Translator
  @en = {
    internet_connection_lost: "You internet connection has been lost"
    bid_received: "Bid received. New balance $$bid_balance$$"
  }

  @ar = {
    internet_connection_lost: "ra7et el connection"
    bid_received: "Bid received. New balance $$bid_balance$$"
  }

  # you can place the variables above in here too
  # or you can have them in different files. Organize stuff as needed
  @get_translations: (locale) ->
    switch (locale)
      when 'en'
        @en
      when 'ar'
        @ar

  @translate: (val, interpolation) ->
    # get locale from meta
    locale = $("meta[name='locale']").attr("content") || "en"

    # get the translation for the val
    translation = Translator.get_translations(locale)[val]

    # substitute values
    for k,v of interpolation
      translation = translation.replace(k, v)

    return translation

window.Translator = Translator

像这样称呼你Translator

message = Translator.translate("bid_received", { "$$bid_balance$$": "$10.00" })
console.log(message)
于 2015-04-09T15:14:14.520 回答
0

只是想在这里插话,因为这是我在一些项目中必须定期做的事情。它并不漂亮,但它是迄今为止我能够提出的最佳解决方案。

使用上面的示例代码:

networks = $('#account_offering_network_id').html()
select_network_options = new Option("Select Account First", "", true, false)

我将假设您的 HTML 代码如下所示:

<select id="account_offering_network_id">
    ...you generate a list of stuff here...
</select>

但您真正的问题是您希望翻译文本“首先选择帐户”。所以这就是我所做的:

<select id="account_offering_network_id" data-default-option-text="Select Account First">
  ...you generate a list of stuff here...
</select>

然后在你的咖啡脚本中,你已经有了这个:

networks = $('#account_offering_network_id').html()

要访问翻译后的值(您在 HTML / ERB 文件中而不是您的咖啡脚本文件中定义),您可以按以下方式访问它:

networks = $('#account_offering_network_id').html()
default_text = $('#account_offering_network_id').attr('data-default-option-text');

当然,在您的 ERB 文件中,您不会传递硬编码的英文翻译,因为您需要当前的语言环境翻译,因此您的实际选择框定义将如下所示:

<select id="account_offering_network_id" data-default-option-text="<%=I18n.t("views.default_select_text")%>">
  ...you generate a list of stuff here...
</select>

这将为您提供您想要在您的咖啡脚本代码中访问的任何内容的翻译版本,该代码可通过您正在使用的任何元素的数据属性访问。

就像我说的 - 它不是很棒,但它工作得非常好,我经常使用它。

于 2014-02-19T20:57:38.003 回答