Skip to content

Instantly share code, notes, and snippets.

@lafeber
Created August 16, 2011 08:44
Show Gist options
  • Save lafeber/1148675 to your computer and use it in GitHub Desktop.
Save lafeber/1148675 to your computer and use it in GitHub Desktop.
A rake file for managing multiple large translation files
begin
require 'ya2yaml'
rescue LoadError
print "The locales tasks were not loaded, since ya2yaml gem is not present. Don't worry if this is a production machine, it is required for development only.\n"
else
LOCALES_PATHS = ["#{Rails.root}/config/locales/", "#{Rails.root}/config/locales/activerecord/", "#{Rails.root}/config/locales/authlogic/", "#{Rails.root}/config/locales/notification_templates/"]
MASTER_LOCALE = "en"
IGNORE_FILES = %w(en.yml en-UK.yml)
class Hash
def extract_untranslated(hash)
target = {}
self.keys.each do |key|
if self[key].is_a? Hash and hash[key]
subtree = self[key].extract_untranslated(hash[key])
target[key] = subtree unless subtree.empty?
next
end
target[key] = self[key] unless hash[key] || self[key] == {}
end
target
end
end
namespace :locales do
$KCODE = 'UTF8'
# Extract the untranslated hashes from translation files (all but en.yml) and put them in a new file.
#
task :extract do
LOCALES_PATHS.each do |locale_path|
Dir["#{locale_path}*.yml"].each do |file_name|
master_file_name = "#{locale_path}#{MASTER_LOCALE}.yml"
master = YAML::load_file master_file_name
bare_file_name = File.basename(file_name)
if IGNORE_FILES.include?(bare_file_name)
puts "- skipping master file and files we maintain ourselves"
next
end
language_code = File.basename(file_name, '.yml')
new_locale_path = locale_path.gsub('locales', "newlocales/#{language_code}")
slave = YAML::load_file(file_name)
unless slave[language_code]
puts "-> ERROR on #{File.basename(file_name)}: can't find key '#{language_code}'!"
next
end
extract = master[MASTER_LOCALE].extract_untranslated(slave[language_code])
if extract.empty?
puts "- skipping #{File.basename(file_name)} (contained the same keys)"
else
final = { language_code => extract }
Dir.mkdir(new_locale_path) unless File.exists?(new_locale_path)
File.open(new_locale_path + bare_file_name, 'w') do |file|
file.write final.ya2yaml.gsub(/\s+$/, '')
end
puts "+ build new file #{new_locale_path + bare_file_name} for translation company"
end
end
end
end
# Merge the translated extracts back into the original translation files.
#
task :merge do
LOCALES_PATHS.each do |locale_path|
Dir["#{locale_path}*.yml"].each do |file_name|
language_code = File.basename(file_name, '.yml')
# the new translations...
new_translations_file = file_name.gsub('locales', "newlocales/#{language_code}")
unless File.exists?(new_translations_file)
puts "- no new translations for #{language_code}"
next
end
original_translations = YAML::load_file(file_name)
new_translations = YAML::load_file(new_translations_file)
merged = original_translations[language_code].deep_merge(new_translations[language_code])
final = { language_code => merged }
# write the merged translations to the original file
File.open(file_name, 'w') do |file|
file.write final.ya2yaml.gsub(/\s+$/, '')
end
# delete the new translations file
File.delete(new_translations_file)
puts "+ merged #{File.basename(file_name)} in original, deleted temp file."
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment