And*_*rao 18 ruby sorting yaml internationalization
我一直在尝试用Ruby对i18n翻译YAML文件进行排序,这样我就能以更好,更有条理的方式管理新翻译,但我一直想知道是否有什么可以轻松完成任务.
我找到了一个YAML文件编写器,所以我可以将哈希写入文件,但我的问题是正确排序哈希.如果我得到哈希h,h.sort返回一个数组,我仍然没有想出一个简单的方法来做到这一点.
我有这样的YAML文件:
pt-br:
global:
misc:
total: "Total"
all: "Todos"
close: "Fechar"
cancel: "Cancelar"
crud:
access: "Acessar"
back: "Voltar"
edit: "Editar"
confirm: "Confirmar"
send: "Enviar"
...
Run Code Online (Sandbox Code Playgroud)
(文件大于此)
但我想以这种方式对它们进行排序:
pt-br:
global:
crud:
access: "Acessar"
back: "Voltar"
confirm: "Confirmar"
edit: "Editar"
send: "Enviar"
misc:
all: "Todos"
cancel: "Cancelar"
close: "Fechar"
total: "Total"
Run Code Online (Sandbox Code Playgroud)
我认为一些简单的递归方法可以帮助我这样:
def translation_sort(h)
if h.class == Hash
h = h.sort
h.each{|item| translation_sort(item)}
end
h
end
require "yaml"
h=YAML.load_file(File.open("~/pt-br.sample.yml"))
translation_sort(h)
Run Code Online (Sandbox Code Playgroud)
luc*_*tte 10
实际上这是一个很好的问题.你想深刻排序哈希.所以我不喜欢重新发明轮子,然后我搜索了一个很好的实现,我找到了一个我喜欢的.看看它https://gist.github.com/1083930.它工作正常.
小智 9
您不应该像其他答案中建议的那样使用YAML库.当你使用重音符和特殊字符时,它会搞砸长字符串值的格式化,删除你的注释并吐出不可读的字符转义符(你会这样做,因为你正在做i18n).使用我创建的这个gem:
https://github.com/redealumni/i18n_yaml_sorter
它只会对文件中的行进行排序,因此所有内容都将保持原始yaml上的样式(您的重音符号,用于输入字符串的YAML构造,缩进等).它将与深度嵌套的yamls一起使用,结果非常可靠.宝石包括测试,它对红宝石1.8或1.9有好处.
它附带一个TextMate Bundle(Shift + Command + S)和一个Rails rake任务,因此您可以在编辑器中轻松地立即对文件进行排序.这真的很快.
为了说明差异:
原版的:
pt-BR:
# Note how this is a nice way of inputing
# paragraphs of text in YAML.
apples: >
Maçãs são boas,
só não coma
seus iPods!
grapes: Não comemos elas.
bananas: |
Bananas são "legais":
- Elas são <b> doces </b>.
isto: não é chave
Por isto todos gostam de bananas!
Run Code Online (Sandbox Code Playgroud)
YAML :: dump的结果:
pt-BR:
apples: "Ma\xC3\xA7\xC3\xA3s s\xC3\xA3o boas, s\xC3\xB3 n\xC3\xA3o coma seus iPods!\n"
bananas: "Bananas s\xC3\xA3o \"legais\":\n - Elas s\xC3\xA3o <b> doces </b>.\n isto: n\xC3\xA3o \xC3\xA9 chave\n\n\ Por isto todos gostam de bananas!\n"
grapes: "N\xC3\xA3o comemos elas."
Run Code Online (Sandbox Code Playgroud)
结果来自i18n_yaml_sorter:
pt-BR:
# Note how this is a nice way of inputing
# paragraphs of text in YAML.
apples: >
Maçãs são boas,
só não coma
seus iPods!
bananas: |
Bananas são "legais":
- Elas são <b> doces </b>.
isto: não é chave
Por isto todos gostam de bananas!
grapes: Não comemos elas.
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/1083930无法正常工作.它只对哈希键进行深度排序,但是哈希值也是哈希值.在我需要深度排序哈希的用例中,哈希总是一棵树,其中键是标签,值是(子)树(如果是哈希)或叶子(否则).我只需要对树的标签进行深度排序.
我懂了
before: {"a":[2,10,{"5":null,"1":null,"3":null}],"x":{"5":null,"1":null,"3":null},"a2":{"5":[2,10,5],"1":null,"3":null}}
after: {"a":[2,10,{"5":null,"1":null,"3":null}],"a2":{"1":null,"3":null,"5":[2,10,5]},"x":{"1":null,"3":null,"5":null}}
Run Code Online (Sandbox Code Playgroud)
有了这个
require 'active_support'
def deeply_sort_hash(object)
return object unless object.is_a?(Hash)
hash = RUBY_VERSION >= '1.9' ? Hash.new : ActiveSupport::OrderedHash.new
object.each { |k, v| hash[k] = deeply_sort_hash(v) }
sorted = hash.sort { |a, b| a[0].to_s <=> b[0].to_s }
hash.class[sorted]
end
Run Code Online (Sandbox Code Playgroud)
使用Rails 3 .2.13,Ruby 1.9.3p489:
我刚刚使用了i18n_yaml_sorter gem(https://github.com/redealumni/i18n_yaml_sorter).
只需添加到您的Gemfile:
gem 'i18n_yaml_sorter', group: :development
Run Code Online (Sandbox Code Playgroud)
然后运行 rake任务来对语言环境的文件进行排序:
rake i18n:sort
Run Code Online (Sandbox Code Playgroud)
工作完美,即使宝石最后一次创作2年前.最多花了5分钟.
在 Ruby 1.8 中,哈希值没有特定的顺序,因此您不能仅对它们进行排序。
你可以猴子修补/覆盖这样的to_yaml方法:Hash
#!/usr/local/bin/ruby -w
require 'yaml'
class Hash
def to_yaml(opts = {})
YAML::quick_emit(self, opts) do |out|
out.map(taguri, to_yaml_style) do |map|
keys.sort.each do |k|
v = self[k]
map.add(k, v)
end
end
end
end
end
dict = YAML.load($<.read)
puts dict.to_yaml
Run Code Online (Sandbox Code Playgroud)
当然,确切的细节可能取决于您的 YAML/Ruby 版本。上面的示例适用于 Ruby 1.8.6。
| 归档时间: |
|
| 查看次数: |
12158 次 |
| 最近记录: |