Class: Interpret::Translation
- Inherits:
-
I18n::Backend::ActiveRecord::Translation
- Object
- I18n::Backend::ActiveRecord::Translation
- Interpret::Translation
- Defined in:
- app/models/interpret/translation.rb
Class Method Summary collapse
- .allowed ⇒ Object
-
.dump ⇒ Object
Dump all contents from *.yml locale files into the database.
-
.export(translations) ⇒ Object
Generate a hash from the given translations.
-
.get_tree(lang = I18n.default_locale) ⇒ Object
Generates a hash representing the tree structure of the translations for the given locale.
-
.import(file) ⇒ Object
Import the contents of the given .yml locale file into the database backend.
-
.update ⇒ Object
Run a smart update from the translations in .yml files into the databse backend.
Class Method Details
.allowed ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'app/models/interpret/translation.rb', line 36 def allowed s = order("") if Interpret.wild_blacklist.any? black_keys = Interpret.wild_blacklist.map{|x| "#{CGI.escape(x)}%"} s = s.where(arel_table[:key].does_not_match_all(black_keys)) end if Interpret.fixed_blacklist.any? black_keys = Interpret.fixed_blacklist.map{|x| "#{CGI.escape(x)}"} s = s.where(arel_table[:key].does_not_match_all(black_keys)) end s end |
.dump ⇒ Object
Dump all contents from *.yml locale files into the database. If Interpret.soft is set to false, all existing translations will be removed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'app/models/interpret/translation.rb', line 117 def dump files = Dir[Rails.root.join("config", "locales", "*.yml").to_s] delete_all unless Interpret.soft records = [] files.each do |f| ar = YAML.load_file f locale = ar.keys.first records += parse_hash(ar.first[1], locale) end # TODO: Replace with activerecord-import bulk inserts transaction do records.each {|x| x.save(:validate => false)} end end |
.export(translations) ⇒ Object
Generate a hash from the given translations. That hash can be ya2yaml’ized to get a standard .yml locale file.
71 72 73 74 75 76 77 78 79 80 81 |
# File 'app/models/interpret/translation.rb', line 71 def export(translations) res = LazyHash.build_hash translations.each do |e| LazyHash.add(res, "#{e.locale}.#{e.key}", e.value) end if res.any? && res.keys.size != 1 raise IndexError, "Generated hash must have only one root key. Your translation data in database may be corrupted." end res end |
.get_tree(lang = I18n.default_locale) ⇒ Object
Generates a hash representing the tree structure of the translations for the given locale. It includes only “folders” in the sense of locale keys that includes some real translations, or other keys.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'app/models/interpret/translation.rb', line 53 def get_tree(lang = I18n.default_locale) t = arel_table all_trans = locale(lang).select(t[:key]).where(t[:key].matches("%.%")).all tree = LazyHash.build_hash all_trans = all_trans.map{|x| x.key.split(".")[0..-2].join(".")}.uniq all_trans.each do |x| LazyHash.add(tree, x, {}) end # Generate a new clean hash without the proc's from LazyHash. # Includes a root level for convenience, to be exactly like the # structure of a .yml file which has the "en" root key for example. {"index" => eval(tree.inspect)} end |
.import(file) ⇒ Object
Import the contents of the given .yml locale file into the database backend. If a given key already exists in database, it will be overwritten, otherwise it won’t be touched. This means that it won’t delete any existing translation, it only overwrites the ones you give in the file.
The language will be obtained from the first unique key of the yml file.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'app/models/interpret/translation.rb', line 91 def import(file) hash = YAML.load file raise ArgumentError, "the YAML file must contain an unique first key representing the locale" unless hash.keys.count == 1 lang = hash.keys.first unless lang.to_s == I18n.locale.to_s raise ArgumentError, "the language doesn't match" end records = parse_hash(hash.first[1], lang) transaction do records.each do |x| if tr = locale(lang).find_by_key(x.key) tr.value = x.value tr.save! else x.save! end end end end |
.update ⇒ Object
Run a smart update from the translations in .yml files into the databse backend. It issues a merging from both, comparing each key present in the db with the one from the yml file.
The use case beyond this arquitecture presuposes some things:
1) You’re working in development mode with the default I18n backend, that is with the translations in the config/locales/*.yml files.
2) Your application is deployed in production and running well. Also, it has support to modify it’s contents (from this very gem of course) on live, so its possible that your customer has changed a sentence or a title of the site. And you want to preserve that.
3) In general, from the very moment you choose to give the users (or admins) of your site the ability to change the contents, that contents are no longer part of the “project” (are checked in in git, to be specific), they are now part of the dynamic contents of the site just as if they were models in your db.
In development, you define a “content layout” in the sense of a specific locale keys hierarchy. How many paragraphs are in your views, how many titles, etc… But the real paragraphs are in the production database.
So, with this “update” action, you are updating that “contents layout” with the new one you just designed in development.
Also keep in mind that rails let you have a diferent locale key hierarchy for each language, and this behaviour is prohibited in interpret. Here, the I18n.default_locale configured in your app is considered the main one, that is, the only language that can be trusted to have all the required and correct locale keys. This will be used to check for inconsitent translations into other languages, knowing what you haven’t translated yet.
What does all that means?
-
First of all, get the locale keys for the main language from yml files.
-
For all of these locale keys, do:
-
If the key is not present in the db, it’s new. So, create a new
entry for that key in the main language. If the key also exists in some other languages in yml files, also create the entry for that languages. But, do not create entries for the languages that does not have this key. Later you will be notified about that missing translations.
-
If the key already exists in the db, do nothing. Maybe somone has
changed that content in production, and you don’t want to lose that. Or maybe you do want to change that content, because you just added the correct sentence in the yml files. It’s up to you to do the right thing. Also, if the key is missing in other languages in database but present in yml files, create the new entry for that language.
-
If a key is present in the db, but not in the new ones, remove
it. You have removed it from the new content layout, so it’s no longer needed.
-
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'app/models/interpret/translation.rb', line 192 def update files = Dir[Rails.root.join("config", "locales", "*.yml").to_s] @languages = {} files.each do |f| ar = YAML.load_file f lang = ar.keys.first if @languages.has_key?(lang.to_s) @languages[lang.to_s] = @languages[lang.to_s].deep_merge(ar.first[1]) else @languages[lang.to_s] = ar.first[1] end end sync(@languages[I18n.default_locale.to_s]) end |