Rails yml 文件中嵌入 erb,i18n 如何重新加载 yml?

michael_roshen · 2015年04月27日 · 最后由 xiaohui_zhangxh 回复于 2017年04月17日 · 2446 次阅读

在做 i18n 国际化的时候,遇到下面问题,有很多 key 是相近的,为了简化一点在网上找到解决办法,就是在 yml 文件中嵌入 ruby 脚本

xx_01_size: 01:00 点 xx_02_size: 02:00 点 xx_03_size: 03:00 点 xx_04_size: 04:00 点 xx_05_size: 05:00 点 xx_06_size: 06:00 点 xx_07_size: 07:00 点 xx_08_size: 08:00 点 xx_09_size: 09:00 点 .. ..

human:
  <% 1.upto 24 do |i|%>
    <% if i<10 %>
  xx_0<%= i %>_size: 0<%= i %>:00点入店
    <% else %>
  xx_<%= i %>_size: <%= i %>:00点入店
    <% end %>
  <% end %>
  <% 1.upto 24 do |i|%>
    <% if i<10 %>
  xx_0<%= i %>_size: 0<%= i %>:00点入店
    <% else %>
  xx_<%= i %>_size: <%= i %>:00点入店
    <% end %>
  <% end %>

那么解析的时候就不能简单的通过 load 来进行解析

错误的写法:

YAML::load(IO.read(File.join('/home/abc/commerce/config', 'locales', 'cn.yml')))
Psych:0:SyntaxError: (<unknown>): mapping values are not allowed here at line 223 column 34

正确的写法: 通过 ERB.new().result 来先对 ruby 脚本进行解析成字符串,再进行 YAML::load

YAML::load(ERB.new(IO.read(File.join('/home/abc/commerce/config', 'locales', 'cn.yml'))).result)

但是 rails 中 i18n 国际化的时候,只需要把 yml 文件加入到 load_path 就可以了,加入到 load_path 后,默认的加载方式是 YAML::load 如何利用新的写法进行加载呢?

#1 楼 @lolychee 你说的是这个吧

# app/views/home/index.html.erb
<%=t 'greet_username', user: "Bill", message: "Goodbye" %>
# config/locales/en.yml
en:
  greet_username: "%{message}, %{user}!"

这个我看到了,但是这个只能在 value 里面传参数,上面的需求是 key 也是动态的

修改你的cn.ymlcn.rb,然后参照下面的代码:

_, data = IO.read(__FILE__).split(/^__END__$/, 2)

counter = 10
YAML.load(ERB.new(data).result(binding))

__END__
en:
  human:
    <% 1.upto counter do |i|%>
    xx_<%=  i %>: <%= i %>
    <% end %>

进入 Rails console 调试看看结果:

[1] pry(main)> I18n.t('human')
=> {:xx_1=>1, :xx_2=>2, :xx_3=>3, :xx_4=>4, :xx_5=>5, :xx_6=>6, :xx_7=>7, :xx_8=>8, :xx_9=>9, :xx_10=>10}
需要 登录 后方可回复, 如果你还没有账号请 注册新账号