tolk 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/javascripts/tolk/actions.js +30 -0
  3. data/app/assets/javascripts/tolk/application.js +3 -4
  4. data/app/assets/javascripts/tolk/interpolations.js +21 -0
  5. data/app/assets/javascripts/tolk/jquery-1.9.1.min.js +5 -0
  6. data/app/assets/javascripts/tolk/layout.js +17 -0
  7. data/app/assets/javascripts/tolk/libraries.js +1 -0
  8. data/app/assets/stylesheets/tolk/application.css +4 -2
  9. data/app/assets/stylesheets/tolk/screen.css +104 -38
  10. data/app/controllers/tolk/application_controller.rb +5 -4
  11. data/app/controllers/tolk/locales_controller.rb +51 -12
  12. data/app/controllers/tolk/searches_controller.rb +3 -3
  13. data/app/helpers/tolk/application_helper.rb +22 -6
  14. data/app/models/tolk/locale.rb +96 -95
  15. data/app/models/tolk/phrase.rb +4 -5
  16. data/app/models/tolk/translation.rb +53 -11
  17. data/app/views/layouts/tolk/application.html.erb +6 -10
  18. data/app/views/tolk/locales/all.html.erb +14 -9
  19. data/app/views/tolk/locales/index.html.erb +1 -4
  20. data/app/views/tolk/locales/show.html.erb +14 -9
  21. data/app/views/tolk/searches/_form.html.erb +2 -2
  22. data/app/views/tolk/searches/show.html.erb +15 -10
  23. data/config/initializers/will_paginate.rb +18 -0
  24. data/config/routes.rb +4 -0
  25. data/lib/generators/tolk/install_generator.rb +44 -0
  26. data/lib/generators/tolk/templates/initializer.erb +412 -0
  27. data/lib/generators/{tolk_migration/templates/migrate/create_tolk_tables.rb → tolk/templates/migration.rb} +0 -0
  28. data/lib/generators/tolk/utils.rb +35 -0
  29. data/lib/tasks/tolk_tasks.rake +14 -2
  30. data/lib/tolk.rb +13 -2
  31. data/lib/tolk/config.rb +87 -0
  32. data/lib/tolk/engine.rb +18 -0
  33. data/lib/tolk/export.rb +27 -0
  34. data/lib/tolk/import.rb +23 -5
  35. data/lib/tolk/pagination.rb +28 -0
  36. data/lib/tolk/sync.rb +25 -9
  37. data/lib/tolk/version.rb +2 -2
  38. data/lib/tolk/yaml.rb +29 -0
  39. metadata +113 -40
  40. data/app/assets/javascripts/tolk/controls.js +0 -963
  41. data/app/assets/javascripts/tolk/dragdrop.js +0 -972
  42. data/app/assets/javascripts/tolk/effects.js +0 -1120
  43. data/app/assets/javascripts/tolk/prototype.js +0 -4221
  44. data/init.rb +0 -8
  45. data/lib/generators/tolk_migration/tolk_migration_generator.rb +0 -19
@@ -1,15 +1,15 @@
1
1
  module Tolk
2
2
  class SearchesController < Tolk::ApplicationController
3
- before_filter :find_locale
3
+ before_action :find_locale
4
4
 
5
5
  def show
6
- @phrases = @locale.search_phrases(params[:q], params[:scope].to_sym, params[:k], params[:page])
6
+ @phrases = @locale.search_phrases(params[:q], params[:scope].to_sym, params[:k], params[pagination_param])
7
7
  end
8
8
 
9
9
  private
10
10
 
11
11
  def find_locale
12
- @locale = Tolk::Locale.find_by_name!(params[:locale])
12
+ @locale = Tolk::Locale.where('UPPER(name) = UPPER(?)', params[:tolk_locale]).first!
13
13
  end
14
14
  end
15
15
  end
@@ -1,27 +1,43 @@
1
1
  module Tolk
2
2
  module ApplicationHelper
3
+ include Tolk::Pagination::ViewHelper
4
+
3
5
  def format_i18n_value(value)
4
- h(yaml_value(value)).gsub(/\n/, '<br />')
6
+ value = h(yaml_value(value))
7
+ value = highlight_linebreaks(value)
8
+ value = highligh_interpolations(value)
9
+ end
10
+
11
+ def highlight_linebreaks(value)
12
+ value.gsub(/\n/, '<span class="carriage_return" title="Line break"><br /></span>').html_safe
13
+ end
14
+
15
+ def highligh_interpolations(value)
16
+ value.gsub(/%{\w+}/, '<span class="interpolation" title="Leave this word untranslated">\0</span>').html_safe
5
17
  end
6
18
 
7
19
  def format_i18n_text_area_value(value)
8
- yaml_value(value)
20
+ yaml_value(value).to_s.force_encoding("UTF-8")
9
21
  end
10
22
 
11
23
  def yaml_value(value)
12
24
  if value.present?
13
- unless value.is_a?(String)
14
- value = value.respond_to?(:ya2yaml) ? value.ya2yaml(:syck_compatible => true) : value.to_yaml
25
+ unless value.is_a?(String) || value.is_a?(TrueClass) || value.is_a?(FalseClass)
26
+ value = Tolk::YAML.dump(value)
15
27
  end
16
28
  end
17
-
29
+
18
30
  value
19
31
  end
20
32
 
33
+ def boolean_warning
34
+ '<span class="boolean">(Do not translate -- Enter true or false)</span>'.html_safe
35
+ end
36
+
21
37
  def tolk_locale_selection
22
38
  existing_locale_names = Tolk::Locale.all.map(&:name)
23
39
 
24
- pairs = Tolk::Locale::MAPPING.to_a.map(&:reverse).sort_by(&:first)
40
+ pairs = Tolk.config.mapping.to_a.map(&:reverse).sort_by(&:first)
25
41
  pairs.reject {|pair| existing_locale_names.include?(pair.last) }
26
42
  end
27
43
 
@@ -1,55 +1,16 @@
1
+ require 'tolk/config'
2
+ require 'tolk/pagination'
3
+
1
4
  module Tolk
2
5
  class Locale < ActiveRecord::Base
6
+ include Tolk::Pagination::Methods
7
+
3
8
  self.table_name = "tolk_locales"
4
9
 
5
- MAPPING = {
6
- 'ar' => 'Arabic',
7
- 'bs' => 'Bosnian',
8
- 'bt' => 'Bulgarian',
9
- 'ca' => 'Catalan',
10
- 'cz' => 'Czech',
11
- 'da' => 'Danish',
12
- 'de' => 'German',
13
- 'dsb' => 'Lower Sorbian',
14
- 'el' => 'Greek',
15
- 'en' => 'English',
16
- 'es' => 'Spanish',
17
- 'et' => 'Estonian',
18
- 'fa' => 'Persian',
19
- 'fi' => 'Finnish',
20
- 'fr' => 'French',
21
- 'he' => 'Hebrew',
22
- 'hr' => 'Croatian',
23
- 'hsb' => 'Upper Sorbian',
24
- 'hu' => 'Hungarian',
25
- 'id' => 'Indonesian',
26
- 'is' => 'Icelandic',
27
- 'it' => 'Italian',
28
- 'jp' => 'Japanese',
29
- 'ko' => 'Korean',
30
- 'lo' => 'Lao',
31
- 'lt' => 'Lithuanian',
32
- 'lv' => 'Latvian',
33
- 'mk' => 'Macedonian',
34
- 'nl' => 'Dutch',
35
- 'no' => 'Norwegian',
36
- 'pl' => 'Polish',
37
- 'pt-br' => 'Portuguese (Brazilian)',
38
- 'pt-PT' => 'Portuguese (Portugal)',
39
- 'ro' => 'Romanian',
40
- 'ru' => 'Russian',
41
- 'se' => 'Swedish',
42
- 'sk' => 'Slovak',
43
- 'sl' => 'Slovenian',
44
- 'sr' => 'Serbian',
45
- 'sw' => 'Swahili',
46
- 'th' => 'Thai',
47
- 'tr' => 'Turkish',
48
- 'uk' => 'Ukrainian',
49
- 'vi' => 'Vietnamese',
50
- 'zh-CN' => 'Chinese (Simplified)',
51
- 'zh-TW' => 'Chinese (Traditional)'
52
- }
10
+ def self._dump_path
11
+ # Necessary to acces rails.root at runtime !
12
+ @dump_path ||= Tolk.config.dump_path.is_a?(Proc) ? instance_eval(&Tolk.config.dump_path) : Tolk.config.dump_path
13
+ end
53
14
 
54
15
  has_many :phrases, :through => :translations, :class_name => 'Tolk::Phrase'
55
16
  has_many :translations, :class_name => 'Tolk::Translation', :dependent => :destroy
@@ -57,12 +18,11 @@ module Tolk
57
18
  accepts_nested_attributes_for :translations, :reject_if => proc { |attributes| attributes['text'].blank? }
58
19
  before_validation :remove_invalid_translations_from_target, :on => :update
59
20
 
60
- attr_accessible :name
61
21
  cattr_accessor :locales_config_path
62
- self.locales_config_path = "#{Rails.root}/config/locales"
22
+ self.locales_config_path = self._dump_path
63
23
 
64
24
  cattr_accessor :primary_locale_name
65
- self.primary_locale_name = I18n.default_locale.to_s
25
+ self.primary_locale_name = Tolk.config.primary_locale_name || I18n.default_locale.to_s
66
26
 
67
27
  include Tolk::Sync
68
28
  include Tolk::Import
@@ -81,7 +41,7 @@ module Tolk
81
41
  @_primary_locale = nil if reload
82
42
  @_primary_locale ||= begin
83
43
  raise "Primary locale is not set. Please set Locale.primary_locale_name in your application's config file" unless self.primary_locale_name
84
- find_or_create_by_name(self.primary_locale_name)
44
+ where(name: self.primary_locale_name).first_or_create
85
45
  end
86
46
  end
87
47
 
@@ -93,28 +53,32 @@ module Tolk
93
53
  all - [primary_locale]
94
54
  end
95
55
 
96
- def dump_all(to = self.locales_config_path)
97
- secondary_locales.each do |locale|
98
- File.open("#{to}/#{locale.name}.yml", "w+") do |file|
99
- data = locale.to_hash
100
- data.respond_to?(:ya2yaml) ? file.write(data.ya2yaml(:syck_compatible => true)) : YAML.dump(locale.to_hash, file)
101
- end
102
- end
56
+ def dump_all(*args)
57
+ secondary_locales.each { |locale| locale.dump(*args) }
58
+ end
59
+
60
+ def dump_yaml(name, *args)
61
+ where(name: name).first.dump(*args)
103
62
  end
104
63
 
105
64
  def special_key_or_prefix?(prefix, key)
106
65
  self.special_prefixes.include?(prefix) || self.special_keys.include?(key)
107
66
  end
108
67
 
109
- PLURALIZATION_KEYS = ['none', 'one', 'two', 'few', 'many', 'other']
68
+ # http://cldr.unicode.org/index/cldr-spec/plural-rules - TODO: usage of 'none' isn't standard-conform
69
+ PLURALIZATION_KEYS = ['none', 'zero', 'one', 'two', 'few', 'many', 'other']
110
70
  def pluralization_data?(data)
111
71
  keys = data.keys.map(&:to_s)
112
72
  keys.all? {|k| PLURALIZATION_KEYS.include?(k) }
113
73
  end
114
74
  end
115
75
 
76
+ def dump(to = self.locales_config_path, exporter = Tolk::Export)
77
+ exporter.dump(name: name, data: to_hash, destination: to)
78
+ end
79
+
116
80
  def has_updated_translations?
117
- translations.count(:conditions => {:'tolk_translations.primary_updated' => true}) > 0
81
+ translations.where('tolk_translations.primary_updated' => true).count > 0
118
82
  end
119
83
 
120
84
  def phrases_with_translation(page = nil)
@@ -126,22 +90,31 @@ module Tolk
126
90
  end
127
91
 
128
92
  def count_phrases_without_translation
129
- existing_ids = self.translations.all(:select => 'tolk_translations.phrase_id').map(&:phrase_id).uniq
93
+ existing_ids = self.translations(:select => 'tolk_translations.phrase_id').map(&:phrase_id).uniq
130
94
  Tolk::Phrase.count - existing_ids.count
131
95
  end
132
96
 
133
- def phrases_without_translation(page = nil, options = {})
134
- phrases = Tolk::Phrase.scoped(:order => 'tolk_phrases.key ASC')
97
+ def count_phrases_with_updated_translation(page = nil)
98
+ find_phrases_with_translations(page, :'tolk_translations.primary_updated' => true).count
99
+ end
100
+
101
+ def phrases_without_translation(page = nil)
102
+ phrases = Tolk::Phrase.all.order('tolk_phrases.key ASC')
135
103
 
136
- existing_ids = self.translations.all(:select => 'tolk_translations.phrase_id').map(&:phrase_id).uniq
137
- phrases = phrases.scoped(:conditions => ['tolk_phrases.id NOT IN (?)', existing_ids]) if existing_ids.present?
104
+ existing_ids = self.translations(:select => 'tolk_translations.phrase_id').map(&:phrase_id).uniq
105
+ phrases = phrases.where('tolk_phrases.id NOT IN (?)', existing_ids) if existing_ids.present?
106
+
107
+ result = phrases.public_send(pagination_method, page)
108
+ if Rails.version =~ /^4\.0/
109
+ ActiveRecord::Associations::Preloader.new result, :translations
110
+ else
111
+ ActiveRecord::Associations::Preloader.new().preload(result, :translations)
112
+ end
138
113
 
139
- result = phrases.paginate({:page => page, :per_page => Phrase.per_page}.merge(options))
140
- ActiveRecord::Associations::Preloader.new result, :translations
141
114
  result
142
115
  end
143
116
 
144
- def search_phrases(query, scope, key_query, page = nil, options = {})
117
+ def search_phrases(query, scope, key_query, page = nil)
145
118
  return [] unless query.present? || key_query.present?
146
119
 
147
120
  translations = case scope
@@ -151,35 +124,42 @@ module Tolk
151
124
  self.translations.containing_text(query)
152
125
  end
153
126
 
154
- phrases = Tolk::Phrase.scoped(:order => 'tolk_phrases.key ASC')
127
+ phrases = Tolk::Phrase.all.order('tolk_phrases.key ASC')
155
128
  phrases = phrases.containing_text(key_query)
156
129
 
157
- phrases = phrases.scoped(:conditions => ['tolk_phrases.id IN(?)', translations.map(&:phrase_id).uniq])
158
- phrases.paginate({:page => page}.merge(options))
130
+ phrases = phrases.where('tolk_phrases.id IN(?)', translations.map(&:phrase_id).uniq)
131
+ phrases.public_send(pagination_method, page)
159
132
  end
160
133
 
161
- def search_phrases_without_translation(query, page = nil, options = {})
162
- return phrases_without_translation(page, options) unless query.present?
134
+ def search_phrases_without_translation(query, page = nil)
135
+ return phrases_without_translation(page) unless query.present?
163
136
 
164
- phrases = Tolk::Phrase.scoped(:order => 'tolk_phrases.key ASC')
137
+ phrases = Tolk::Phrase.all.order('tolk_phrases.key ASC')
165
138
 
166
- found_translations_ids = Tolk::Locale.primary_locale.translations.all(:conditions => ["tolk_translations.text LIKE ?", "%#{query}%"], :select => 'tolk_translations.phrase_id').map(&:phrase_id).uniq
167
- existing_ids = self.translations.all(:select => 'tolk_translations.phrase_id').map(&:phrase_id).uniq
168
- phrases = phrases.scoped(:conditions => ['tolk_phrases.id NOT IN (?) AND tolk_phrases.id IN(?)', existing_ids, found_translations_ids]) if existing_ids.present?
139
+ found_translations_ids = Tolk::Locale.primary_locale.translations.where(["tolk_translations.text LIKE ?", "%#{query}%"]).to_a.map(&:phrase_id).uniq
140
+ existing_ids = self.translations.select('tolk_translations.phrase_id').to_a.map(&:phrase_id).uniq
141
+ # phrases = phrases.scoped(:conditions => ['tolk_phrases.id NOT IN (?) AND tolk_phrases.id IN(?)', existing_ids, found_translations_ids]) if existing_ids.present?
142
+ phrases = phrases.where(['tolk_phrases.id NOT IN (?) AND tolk_phrases.id IN(?)', existing_ids, found_translations_ids]) if existing_ids.present?
143
+ result = phrases.public_send(pagination_method, page)
144
+ if Rails.version =~ /^4\.0/
145
+ ActiveRecord::Associations::Preloader.new result, :translations
146
+ else
147
+ ActiveRecord::Associations::Preloader.new().preload(result, :translations)
148
+ end
169
149
 
170
- result = phrases.paginate({:page => page}.merge(options))
171
- ActiveRecord::Associations::Preloader.new result, :translations
172
150
  result
173
151
  end
174
152
 
175
153
  def to_hash
176
- { name => translations.each_with_object({}) do |translation, locale|
177
- if translation.phrase.key.include?(".")
178
- locale.deep_merge!(unsquish(translation.phrase.key, translation.value))
179
- else
180
- locale[translation.phrase.key] = translation.value
154
+ data = translations.includes(:phrase).references(:phrases).order(phrases.arel_table[:key]).
155
+ each_with_object({}) do |translation, locale|
156
+ if translation.phrase.key.include?(".")
157
+ locale.deep_merge!(unsquish(translation.phrase.key, translation.value))
158
+ else
159
+ locale[translation.phrase.key] = translation.value
160
+ end
181
161
  end
182
- end }
162
+ { name => data }
183
163
  end
184
164
 
185
165
  def to_param
@@ -191,11 +171,11 @@ module Tolk
191
171
  end
192
172
 
193
173
  def language_name
194
- MAPPING[self.name] || self.name
174
+ Tolk.config.mapping[self.name] || self.name
195
175
  end
196
176
 
197
177
  def get(key)
198
- if phrase = Tolk::Phrase.find_by_key(key)
178
+ if phrase = Tolk::Phrase.where(key: key).first
199
179
  t = self.translations.where(:phrase_id => phrase.id).first
200
180
  t.text if t
201
181
  end
@@ -204,18 +184,37 @@ module Tolk
204
184
  def translations_with_html
205
185
  translations = self.translations.all(:conditions => "tolk_translations.text LIKE '%>%' AND
206
186
  tolk_translations.text LIKE '%<%' AND tolk_phrases.key NOT LIKE '%_html'", :joins => :phrase)
207
- ActiveRecord::Associations::Preloader.new translations, :phrase
187
+ if Rails.version =~ /^4\.0/
188
+ ActiveRecord::Associations::Preloader.new translations, :phrase
189
+ else
190
+ ActiveRecord::Associations::Preloader.new().preload(translations, :phrase)
191
+ end
208
192
  translations
209
193
  end
210
194
 
195
+ def self.rename(old_name, new_name)
196
+ if old_name.blank? || new_name.blank?
197
+ "You need to provide both names, aborting."
198
+ else
199
+ if locale = where(name: old_name).first
200
+ locale.name = new_name
201
+ locale.save
202
+ "Locale ' #{old_name}' was renamed '#{new_name}'"
203
+ else
204
+ "Locale with name '#{old_name}' not found."
205
+ end
206
+ end
207
+ end
208
+
211
209
  private
212
210
 
211
+
213
212
  def remove_invalid_translations_from_target
214
213
  self.translations.target.dup.each do |t|
215
- unless t.valid?
214
+ unless t.valid?
216
215
  self.translations.target.delete(t)
217
216
  else
218
- t.updated_at = Time.current # Silly hax to fool autosave into saving the record
217
+ t.updated_at_will_change!
219
218
  end
220
219
  end
221
220
 
@@ -223,15 +222,17 @@ module Tolk
223
222
  end
224
223
 
225
224
  def find_phrases_with_translations(page, conditions = {})
226
- result = Tolk::Phrase.paginate(:page => page,
227
- :conditions => { :'tolk_translations.locale_id' => self.id }.merge(conditions),
228
- :joins => :translations, :order => 'tolk_phrases.key ASC')
225
+ result = Tolk::Phrase.where({ :'tolk_translations.locale_id' => self.id }.merge(conditions)).joins(:translations).order('tolk_phrases.key ASC').public_send(pagination_method, page)
229
226
 
230
227
  result.each do |phrase|
231
228
  phrase.translation = phrase.translations.for(self)
232
229
  end
233
230
 
234
- ActiveRecord::Associations::Preloader.new result, :translations
231
+ if Rails.version =~ /^4\.0/
232
+ ActiveRecord::Associations::Preloader.new result, :translations
233
+ else
234
+ ActiveRecord::Associations::Preloader.new().preload(result, :translations)
235
+ end
235
236
 
236
237
  result
237
238
  end
@@ -2,12 +2,9 @@ module Tolk
2
2
  class Phrase < ActiveRecord::Base
3
3
  self.table_name = "tolk_phrases"
4
4
 
5
- attr_accessible :key
6
-
7
5
  validates_uniqueness_of :key
8
6
 
9
- cattr_accessor :per_page
10
- self.per_page = 30
7
+ paginates_per 30
11
8
 
12
9
  has_many :translations, :class_name => 'Tolk::Translation', :dependent => :destroy do
13
10
  def primary
@@ -21,8 +18,10 @@ module Tolk
21
18
 
22
19
  attr_accessor :translation
23
20
 
21
+ #scope :red, -> { where(color: 'red') } rather than scope :red, -> { { conditions: { color: 'red' } } }
22
+
24
23
  scope :containing_text, lambda { |query|
25
- { :conditions => ["tolk_phrases.key LIKE ?", "%#{query}%"] }
24
+ where("tolk_phrases.key LIKE ?", "%#{query}%")
26
25
  }
27
26
  end
28
27
  end
@@ -5,7 +5,8 @@ module Tolk
5
5
  scope :containing_text, lambda {|query| where("tolk_translations.text LIKE ?", "%#{query}%") }
6
6
 
7
7
  serialize :text
8
- validates_presence_of :text, :if => proc {|r| r.primary.blank? && !r.explicit_nil }
8
+ serialize :previous_text
9
+ validate :validate_text_not_nil, :if => proc {|r| r.primary.blank? && !r.explicit_nil && !r.boolean?}
9
10
  validate :check_matching_variables, :if => proc { |tr| tr.primary_translation.present? }
10
11
 
11
12
  validates_uniqueness_of :phrase_id, :scope => :locale_id
@@ -14,9 +15,6 @@ module Tolk
14
15
  belongs_to :locale, :class_name => 'Tolk::Locale'
15
16
  validates_presence_of :locale_id
16
17
 
17
- attr_accessible :phrase_id, :locale_id, :text, :primary_updated, :previous_text, :locale, :phrase
18
-
19
- attr_accessor :force_set_primary_update
20
18
  before_save :set_primary_updated
21
19
 
22
20
  before_save :set_previous_text
@@ -27,6 +25,10 @@ module Tolk
27
25
  attr_accessor :explicit_nil
28
26
  before_validation :set_explicit_nil
29
27
 
28
+ def boolean?
29
+ text.is_a?(TrueClass) || text.is_a?(FalseClass) || text == 't' || text == 'f'
30
+ end
31
+
30
32
  def up_to_date?
31
33
  not out_of_date?
32
34
  end
@@ -45,24 +47,48 @@ module Tolk
45
47
 
46
48
  def text=(value)
47
49
  value = value.to_s if value.kind_of?(Fixnum)
48
- super unless value.to_s == text
50
+ if primary_translation && primary_translation.boolean?
51
+ value = case value.to_s.downcase.strip
52
+ when 'true', 't'
53
+ true
54
+ when 'false', 'f'
55
+ false
56
+ else
57
+ self.explicit_nil = true
58
+ nil
59
+ end
60
+ super unless value == text
61
+ else
62
+ value = value.strip if value.is_a?(String) && Tolk.config.strip_texts
63
+ super unless value.to_s == text
64
+ end
49
65
  end
50
66
 
51
67
  def value
52
68
  if text.is_a?(String) && /^\d+$/.match(text)
53
69
  text.to_i
70
+ elsif (primary_translation || self).boolean?
71
+ %w[true t].member?(text.to_s.downcase.strip)
54
72
  else
55
73
  text
56
74
  end
57
75
  end
58
76
 
59
77
  def self.detect_variables(search_in)
60
- case search_in
78
+ variables = case search_in
61
79
  when String then Set.new(search_in.scan(/\{\{(\w+)\}\}/).flatten + search_in.scan(/\%\{(\w+)\}/).flatten)
62
80
  when Array then search_in.inject(Set[]) { |carry, item| carry + detect_variables(item) }
63
81
  when Hash then search_in.values.inject(Set[]) { |carry, item| carry + detect_variables(item) }
64
82
  else Set[]
65
83
  end
84
+
85
+ # delete special i18n variable used for pluralization itself (might not be used in all values of
86
+ # the pluralization keys, but is essential to use pluralization at all)
87
+ if search_in.is_a?(Hash) && Tolk::Locale.pluralization_data?(search_in)
88
+ variables.delete_if {|v| v == 'count' }
89
+ else
90
+ variables
91
+ end
66
92
  end
67
93
 
68
94
  def variables
@@ -92,14 +118,25 @@ module Tolk
92
118
  end
93
119
  end
94
120
 
95
- self.text = nil if primary_translation.text.class != self.text.class
121
+ if primary_translation.boolean?
122
+ self.text = case self.text.to_s.strip
123
+ when 'true'
124
+ true
125
+ when 'false'
126
+ false
127
+ else
128
+ nil
129
+ end
130
+ elsif primary_translation.text.class != self.text.class
131
+ self.text = nil
132
+ end
96
133
  end
97
134
 
98
135
  true
99
136
  end
100
137
 
101
138
  def set_primary_updated
102
- self.primary_updated = self.force_set_primary_update ? true : false
139
+ self.primary_updated = false
103
140
  true
104
141
  end
105
142
 
@@ -110,12 +147,17 @@ module Tolk
110
147
 
111
148
  def check_matching_variables
112
149
  unless variables_match?
113
- if primary_translation.variables.empty? || primary_translation.variables.class == Set
114
- self.errors.add(:text, "The original does not contain variables, so they should not be included.")
150
+ if primary_translation.variables.empty?
151
+ self.errors.add(:variables, "The primary translation does not contain substitutions, so this should neither.")
115
152
  else
116
- self.errors.add(:text, "The translation should contain the variables #{primary_translation.to_a.to_sentence}.")
153
+ self.errors.add(:variables, "The translation should contain the substitutions of the primary translation: (#{primary_translation.variables.to_a.join(', ')}), found (#{self.variables.to_a.join(', ')}).")
117
154
  end
118
155
  end
119
156
  end
157
+
158
+ def validate_text_not_nil
159
+ return unless text.nil?
160
+ errors.add :text, :blank
161
+ end
120
162
  end
121
163
  end