Module: TranslationCenter

Defined in:
lib/translation_center/engine.rb,
lib/translation_center/version.rb,
lib/afalkear_translation_center.rb,
app/models/translation_center/category.rb,
app/models/translation_center/translation.rb,
lib/translation_center/translation_helpers.rb,
app/helpers/translation_center/center_helper.rb,
app/models/translation_center/activity_query.rb,
lib/translation_center/translations_transfer.rb,
app/models/translation_center/translation_key.rb,
app/helpers/translation_center/categories_helper.rb,
app/helpers/translation_center/application_helper.rb,
app/helpers/translation_center/translations_helper.rb,
app/controllers/translation_center/center_controller.rb,
app/helpers/translation_center/translation_keys_helper.rb,
app/controllers/translation_center/categories_controller.rb,
app/controllers/translation_center/application_controller.rb,
app/controllers/translation_center/translations_controller.rb,
lib/generators/translation_center/install/install_generator.rb,
lib/generators/translation_center/add_lang/add_lang_generator.rb,
app/controllers/translation_center/translation_keys_controller.rb

Defined Under Namespace

Modules: ApplicationHelper, CategoriesHelper, CenterHelper, TranslationKeysHelper, TranslationsHelper Classes: ActivityQuery, AddLangGenerator, ApplicationController, CategoriesController, Category, CenterController, Engine, InstallGenerator, Translation, TranslationKey, TranslationKeysController, TranslationsController

Constant Summary collapse

VERSION =
"1.8.4"
CONFIG =
{'enabled' => false, 'inspector' => 'missing', 'lang' => {'en' => {'name' => 'English', 'direction' => 'ltr'}}, 'yaml_translator_identifier' => '[email protected]', 'i18n_source' => 'yaml', 'yaml2db_translations_accepted' => true,
'accept_admin_translations' => true,  'save_default_translation' => true, 'identifier_type' => 'email', 'translator_type' => 'User' }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.collect_keys(scope, translations) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/translation_center/translations_transfer.rb', line 14

def self.collect_keys(scope, translations)
  full_keys = []
  translations.to_a.each do |key, translations|
    new_scope = scope.dup << key
    if translations.is_a?(Hash)
      full_keys += collect_keys(new_scope, translations)
    else
      full_keys << new_scope.join('.')
    end
  end
  return full_keys
end

.db2yaml(locale = nil) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/translation_center/translations_transfer.rb', line 109

def self.db2yaml(locale=nil)
  locales = locale.blank? ? I18n.available_locales : [locale.to_sym]

  # for each locale build a hash for the translations and write to file
  locales.each do |locale|
    result = {}
    I18n.locale = locale
    puts "Started exporting translations in #{locale}"
    TranslationCenter::TranslationKey.translated(locale).each do |key|
      begin
        key.add_to_hash(result, locale)  
      rescue
        puts "Error writing key: #{key.name} to yaml for #{locale}"
      end
    end
    File.open("config/locales/#{locale.to_s}.yml", 'w') do |file|
      file.write({locale.to_s => result}.ya2yaml)
    end
    puts "Done exporting translations of #{locale} to #{locale.to_s}.yml"
  end 
end

.get_translation_from_hash(key, hash) ⇒ Object

needed for interpolated translations in I18n



4
5
6
7
8
9
10
11
12
# File 'lib/translation_center/translations_transfer.rb', line 4

def self.get_translation_from_hash(key, hash)
  path = key.split('.')
  last_step = hash
  path.each do |step|
    break if last_step.blank? || !last_step.is_a?(Hash)
    last_step = last_step[step.to_s.to_sym]
  end
  last_step
end

.included(base) ⇒ Object



23
24
25
26
27
# File 'lib/translation_center/translation_helpers.rb', line 23

def self.included(base)
  base.class_eval do
    alias_method_chain :translate, :adding if(TranslationCenter::CONFIG['enabled'])
  end
end

.prepare_translatorObject

Return the default translator by building and returning the translator object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/translation_center/translation_helpers.rb', line 4

def self.prepare_translator

  translator = TranslationCenter::CONFIG['translator_type'].camelize.constantize.where(TranslationCenter::CONFIG['identifier_type'] => TranslationCenter::CONFIG['yaml_translator_identifier']).first
  
  # if translator doesn't exist then create him
  if translator.blank?
    translator = TranslationCenter::CONFIG['translator_type'].camelize.constantize.new
    translator.send "#{TranslationCenter::CONFIG['identifier_type']}=", TranslationCenter::CONFIG['yaml_translator_identifier']
    begin
      translator.save(validate: false)
      # needed if the user is using confirmable with devise
      translator.update_attribute(:confirmed_at, Time.now) if translator.attributes.has_key?('confirmed_at')
    rescue
      translator = nil
    end
  end
  translator
end

.yaml2db(locale = nil) ⇒ Object

take the yaml translations and update the db with them



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/translation_center/translations_transfer.rb', line 79

def self.yaml2db(locale=nil)

  # prepare translator by creating the translator if he doesn't exist
  translator = TranslationCenter.prepare_translator

  # if couldn't create translator then print error msg and quit
  if translator.blank?
    puts "ERROR: Unable to create default translator with #{TranslationCenter::CONFIG['identifier_type']} = #{TranslationCenter::CONFIG['yaml_translator_identifier']}"
    puts "Create this user manually and run the rake again"
    return false
  end

  # Make sure we've loaded the translations
  I18n.backend.send(:init_translations)
  puts "#{I18n.available_locales.size} #{I18n.available_locales.size == 1 ? 'locale' : 'locales'} available: #{I18n.available_locales.join(', ')}"

  # Get all keys from all locales
  all_yamls = I18n.backend.send(:translations)
  all_keys = all_yamls.collect do |check_locale, translations|
    collect_keys([], translations).sort
  end.flatten.uniq

  puts "#{all_keys.size} #{all_keys.size == 1 ? 'unique key' : 'unique keys'} found."

  locales = locale.blank? ? I18n.available_locales : [locale.to_sym]

  # create records for all keys that exist in the yaml
  yaml2db_keys(all_keys, translator, locales, all_yamls)
end

.yaml2db_key(locale, translation_key, translator, all_yamls) ⇒ Object

gets the translation of a a key in certian lang and inserts it in the db returns true if the translation was fonud in yaml



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/translation_center/translations_transfer.rb', line 29

def self.yaml2db_key(locale, translation_key, translator, all_yamls)
  I18n.locale = locale
  translation = TranslationCenter::Translation.find_or_initialize_by_translation_key_id_and_lang_and_translator_id(translation_key.id, locale.to_s, translator.id)
  translation.translator_type = TranslationCenter::CONFIG['translator_type']
  
  # get the translation for this key from the yamls
  value = get_translation_from_hash(translation_key.name, all_yamls[locale])

  # if the value is not empty and is different from the existing value the update
  if !value.blank? && value != translation.value
    translation.update_attribute(:value, value)
    # accept this yaml translation
    translation.accept if TranslationCenter::CONFIG['yaml2db_translations_accepted']
    true
  end
end

.yaml2db_keys(keys, translator, locales, all_yamls) ⇒ Object

takes array of keys and creates/updates the keys in the db with translations in the given locales



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/translation_center/translations_transfer.rb', line 47

def self.yaml2db_keys(keys, translator, locales, all_yamls)
  # initialize stats variables
  new_keys = 0
  missing_keys = locales.inject({}) do |memo, lang|
    memo[lang] = 0
    memo
  end

  # for each key create it in the db if it doesn't exist, and add its translation to
  # the db in every locale
  keys.each do |key|

    translation_key = TranslationCenter::TranslationKey.find_or_initialize_by_name(key)
    if translation_key.new_record?
      translation_key.save
      new_keys += 1
    end

    # for each locale create/update its translation
    locales.each do |locale|
      missing_keys[locale] += 1 unless self.yaml2db_key(locale, translation_key, translator, all_yamls)
    end

  end

  puts "found new #{new_keys} key(s)"
  missing_keys.each do |locale, count|
    puts "missing #{count} translation(s) for #{locale}" if count > 0
  end
end

Instance Method Details

#prepare_key(key, options) ⇒ Object

make sure the complete key is build using the options such as scope and count



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/translation_center/translation_helpers.rb', line 40

def prepare_key(key, options)
  complete_key  = key

  # if a scope is passed in options then build the full key
  complete_key = options[:scope].present? ? "#{options[:scope].to_s}.#{complete_key}" : complete_key

  # add the correct count suffix
  if options[:count].present? && options[:count] == 1
    complete_key = "#{complete_key}.one"
  elsif options[:count].present? && options[:count] != 1
    complete_key = "#{complete_key}.other"
  end
  complete_key
end

#translate_with_adding(locale, key, options = {}) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/translation_center/translation_helpers.rb', line 55

def translate_with_adding(locale, key, options = {})
  # handle calling translation with a blank key
  # or translation center tables don't exist
  return translate_without_adding(locale, key, options) if key.blank? || !ActiveRecord::Base.connection.table_exists?('translation_center_translation_keys')

  complete_key = prepare_key(key, options) # prepare complete key

  # add the new key or update it
  translation_key = TranslationCenter::TranslationKey.find_or_create_by(name: complete_key)
  #  UNCOMMENT THIS LATER TO SET LAST ACCESSED AT
  # translation_key.update_attribute(:last_accessed, Time.now)

  # save the default value (Which is the titleized key name as the translation) if the option is enabled and no translation exists for that key in the db
  translation_key.create_default_translation if TranslationCenter::CONFIG['save_default_translation'] && translation_key.translations.in(:en).empty? && !translation_key.has_children?

  # if i18n_source is set to db and not overriden by options then fetch from db
  if TranslationCenter::CONFIG['i18n_source']  == 'db' && options.delete(:yaml).blank?
    val = translation_key.accepted_translation_in(locale).try(:value) || options[:default]
    # replace variables in a translation with passed values
    options.each_pair{ |key, value| val.gsub!("%{#{key.to_s}}", value.to_s) } if val.is_a?(String)

    if val.blank? && !translation_key.has_children?
      # if the key has no translation show the key last identifier to modify
      throw(:exception, I18n::MissingTranslation.new(locale, complete_key, options))
      #translation_value = key.split('.').last
      #return wrap_span(translation_value, translation_key)
    elsif translation_key.has_children?
      # TODO should use ancestors for keys
      #return translation_key.children_translations(locale)
      return wrap_span(translation_key.children_translations(locale), translation_key)
    end
    wrap_span(val, translation_key)
  else
    translation_value = translate_without_adding(locale, key, options)
    translation_value.class == Hash ? translation_value : wrap_span(translation_value, translation_key)
  end
end

#wrap_span(translation, translation_key) ⇒ Object

wraps a span if inspector option is set to all



30
31
32
33
34
35
36
37
# File 'lib/translation_center/translation_helpers.rb', line 30

def wrap_span(translation, translation_key)
  # put the inspector class if inspector is all and the key doesn't belongs to translation_center
  if TranslationCenter::CONFIG['inspector'] == 'all' && translation_key.name.to_s.split('.').first != 'translation_center'
    "<span class='tc-inspector-key' data-locale='#{I18n.locale}' data-type='#{translation_key.status(I18n.locale)}' data-id='#{translation_key.id}'> #{translation} </span>".html_safe
  else
    translation
  end
end