Created
October 20, 2014 07:45
-
-
Save ruuts/a6bfb0c1c06489db9701 to your computer and use it in GitHub Desktop.
i18n missing keys to gengo export/import
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :translator do | |
desc "Export missing translations for a specific locale" | |
task :export_keys => :environment do | |
from = ENV['FROM'] | |
to = ENV['TO'] | |
if from.present? and to.present? | |
translator = Translator.new( | |
from: from.to_sym, | |
to: to.to_sym | |
) | |
missing = translator.export_keys | |
if missing.length > 0 | |
filename = "translate_#{from}_to_#{to}.txt" | |
File.open(filename, 'w') do |file| | |
file.write missing | |
end | |
puts "Created export file: #{filename}" | |
else | |
puts "There are no missing translations from #{from} to #{to}" | |
end | |
else | |
puts "Please provide locale to translate for example:" | |
puts "rake translator FROM=en TO=fr" | |
end | |
end | |
desc "Import missing translations for a specific locale" | |
task :import_keys => :environment do | |
if ENV['FROM'].present? and ENV['TO'].present? and ENV['FILE'].present? | |
translator = Translator.new( | |
from: ENV['FROM'].to_sym, | |
to: ENV['TO'].to_sym | |
) | |
file = File.open(ENV['FILE']) | |
translator.import_keys(file.read) | |
translator.write_locale_file | |
else | |
puts "Please provide the following arguments:" | |
puts "rake translator FROM=en TO=fr FILE=en_to_fr.translate" | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'yaml' | |
class Translator | |
def initialize(options = {}) | |
@from = options[:from] | |
@to = options[:to] | |
@dir = options[:dir] || "config/locales/multilingual" | |
end | |
def prepare_translations_for_missing_keys | |
I18n.with_locale(@from) do | |
result = {} | |
find_missing_keys.each do |key| | |
result[key] = I18n.t(key.gsub("#{@to}.", '')).to_s | |
end | |
result | |
end | |
end | |
def export_keys | |
prepare_translations_for_missing_keys.map do |key, value| | |
"[[[#{key}]]] #{value}" | |
end.join("\n") | |
end | |
def import_keys(import) | |
matches = import.scan %r{ | |
\[\[\[ # key start brackets | |
([^\]]+) # key | |
\]\]\] # key end brackets | |
((.(?!\[\[\[))*) # value until brackets | |
}xm | |
@import = {} | |
matches.each do |match| | |
@import[match[0]] = match[1].to_s.lstrip | |
end | |
@import | |
end | |
def write_locale_file | |
old_yaml = yaml(@to) | |
new_yaml = deflatten_keys(@import) | |
merged_yaml = old_yaml ? old_yaml.deep_merge(new_yaml) : new_yaml | |
File.open(path(@to), 'w') do |file| | |
file.write merged_yaml.to_yaml | |
end | |
end | |
def find_missing_keys | |
yaml_1 = yaml(@from) | |
yaml_2 = yaml(@to) | |
keys_1 = yaml_1.present? ? flatten_keys(yaml_1[yaml_1.keys.first]) : [] | |
keys_2 = yaml_2.present? ? flatten_keys(yaml_2[yaml_2.keys.first]) : [] | |
(keys_1 - keys_2).map {|k| "#{@to}.#{k}" } | |
end | |
private | |
def yaml(locale) | |
YAML.load((File.open(path(locale)) rescue '')) | |
end | |
def path(locale) | |
File.expand_path("#{@dir}/#{locale}.yml") | |
end | |
def deflatten_keys(hash) | |
new_hash = {} | |
hash.each do |k,v| | |
new_hash.deep_merge!( | |
k.split('.').reverse.inject(v) {|a,n| { n => a } } | |
) | |
end | |
new_hash | |
end | |
def flatten_keys(hash, prefix="") | |
keys = [] | |
hash.keys.each do |key| | |
if hash[key].is_a? Hash | |
current_prefix = prefix + "#{key}." | |
keys << flatten_keys(hash[key], current_prefix) | |
else | |
keys << "#{prefix}#{key}" | |
end | |
end | |
prefix == "" ? keys.flatten : keys | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FYI, I made a few changes in my fork. In my 'from' or starting locale I generally break things into multiple files for easier maintenance, so I load all translations differently and then pick that locale instead of just loading from a single file. Thanks again!