air18n 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -182,7 +182,11 @@ module Air18n
182
182
  # I18n.t('foo', :default => 'Foo', :locale => @current_user.preferred_locale)
183
183
  locale = locale.to_sym
184
184
 
185
- default = options[:default] && options[:default].is_a?(String) && options[:default]
185
+ default = if options[:default] && options[:default].is_a?(String)
186
+ options[:default]
187
+ else
188
+ nil
189
+ end
186
190
  overrides_previous_default = !options[:default_is_low_priority]
187
191
 
188
192
  I18n.fallbacks_for(locale).each do |l|
@@ -1,14 +1,18 @@
1
1
  module Air18n
2
2
  class Phrase < ActiveRecord::Base
3
3
  has_many :phrase_translations, :dependent=>:delete_all
4
- has_many :phrase_revisions, :foreign_key => 'key', :primary_key => 'key', :dependent=>:delete_all
4
+ has_many :phrase_revisions, :foreign_key => :key, :primary_key => :key, :dependent=>:delete_all
5
5
  has_many :phrase_screenshots, :foreign_key => 'phrase_key', :primary_key => 'key', :dependent=>:delete_all
6
6
 
7
7
  after_update :mark_translations_stale
8
8
  after_update :record_phrase_revision
9
9
 
10
+ after_create :copy_existing_translations
11
+
10
12
  validates_uniqueness_of :key
11
13
 
14
+ # When we change a phrase's text, we mark its existing translations as
15
+ # stale.
12
16
  def mark_translations_stale
13
17
  translations = PhraseTranslation.find_all_by_phrase_id(id)
14
18
  translations.each do |translation|
@@ -20,6 +24,8 @@ module Air18n
20
24
  end
21
25
  end
22
26
 
27
+ # When we change a phrase's text, we record the text. This is so we have a
28
+ # record of all default texts that a phrase key has taken on in the past.
23
29
  def record_phrase_revision
24
30
  value_hash = compute_value_hash
25
31
  if value_hash.present?
@@ -27,11 +33,52 @@ module Air18n
27
33
  end
28
34
  end
29
35
 
36
+ # When we create a phrase with the same default text as an existing phrase,
37
+ # we copy the older phrase's existing translations over.
38
+ def copy_existing_translations
39
+ existing_phrase = Phrase.
40
+ where(:value => self.value).
41
+ where('`phrases`.id < ?', self.id).
42
+ last
43
+ if existing_phrase.present?
44
+ translations = PhraseTranslation.
45
+ where(:phrase_id => existing_phrase.id).
46
+ latest.
47
+ order('`phrase_translations`.id DESC')
48
+ translations_by_language = translations.group_by do |pt|
49
+ I18n.language_from_locale(pt.locale)
50
+ end
51
+
52
+ # We do some gymnastics here to create the translations so that we
53
+ # create the ones for e.g. "zh" after the ones for "zh-TW" .
54
+ #
55
+ # This is because translations for specific locales are sometimes
56
+ # generated from the more general locale.
57
+ translations_by_language.each do |language, translations|
58
+ translations_with_language_last = translations.sort_by do |pt|
59
+ -pt.locale.to_s.size
60
+ end
61
+ translations_with_language_last.each do |pt|
62
+ PhraseTranslation.create_translation(
63
+ self.id,
64
+ self.key,
65
+ pt.locale,
66
+ pt.value,
67
+ 0, # user ID: 0 means automated
68
+ false, # do xss check? no
69
+ false # allow verification? no
70
+ )
71
+ end
72
+ end
73
+ end
74
+ end
75
+
30
76
  def compute_value_hash
31
77
  value.present? ? Digest::MD5.new.update(value).to_s : ""
32
78
  end
33
79
 
34
80
  # TODO(jkb) retire this method, it is very old and ugly.
81
+ # It is used by the contextual translations code.
35
82
  def self.by_key lookup
36
83
  if !@by_key then
37
84
  @by_key = {}
@@ -1,3 +1,3 @@
1
1
  module Air18n
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -65,6 +65,16 @@ describe Air18n::Backend do
65
65
  it 'should not barf on arrays' do
66
66
  @backend.lookup(I18n.default_locale, ['january', 'february'], @scope).should == nil
67
67
  end
68
+
69
+ it 'should not store or return default hashes' do
70
+ @backend.lookup(
71
+ I18n.default_locale, 'translation hash', @scope, :default => {}
72
+ ).should == nil
73
+ @backend.lookup(I18n.default_locale, 'translation hash', @scope).should == nil
74
+
75
+ # Should not have created a phrase for this new key.
76
+ Air18n::Phrase.find_by_key('translation hash').should_not be_present
77
+ end
68
78
  end
69
79
 
70
80
  context 'I18n backend initialization' do
@@ -3,25 +3,57 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Air18n::Phrase do
6
- context 'revisions' do
7
- it "should keep track of its revisions" do
6
+ context 'creating a new phrase' do
7
+ it 'should keep track of its revisions' do
8
8
  phrase = FactoryGirl.create(:phrase, :key => 'revisions key')
9
- phrase.value = "new value"
9
+ phrase.value = 'new value'
10
10
  phrase.save!
11
11
  phrase.phrase_revisions.size.should == 1
12
- phrase.phrase_revisions.first.value_hash.should == "14979451a8c46ae1691eb3aedab3359d"
12
+ phrase.phrase_revisions.first.value_hash.should == '14979451a8c46ae1691eb3aedab3359d'
13
13
 
14
- phrase.value = "second value"
14
+ phrase.value = 'second value'
15
15
  phrase.save!
16
16
  revisions = phrase.revisions_in_order
17
- revisions.map(&:value_hash).should == ["14979451a8c46ae1691eb3aedab3359d", "5d10ab09a3cd6e0227c2c79fd8e525b7"]
17
+ revisions.map(&:value_hash).should == ['14979451a8c46ae1691eb3aedab3359d', '5d10ab09a3cd6e0227c2c79fd8e525b7']
18
18
 
19
- phrase.value = "new value"
19
+ phrase.value = 'new value'
20
20
  phrase.save!
21
21
  revisions = phrase.revisions_in_order
22
- revisions.map(&:value_hash).should == ["14979451a8c46ae1691eb3aedab3359d", "5d10ab09a3cd6e0227c2c79fd8e525b7"]
23
- Air18n::PhraseRevision.value_from_hash('revisions key', "14979451a8c46ae1691eb3aedab3359d").should == "new value"
24
- Air18n::PhraseRevision.value_from_hash('revisions key', "5d10ab09a3cd6e0227c2c79fd8e525b7").should == "second value"
22
+ revisions.map(&:value_hash).should == ['14979451a8c46ae1691eb3aedab3359d', '5d10ab09a3cd6e0227c2c79fd8e525b7']
23
+ Air18n::PhraseRevision.value_from_hash('revisions key', '14979451a8c46ae1691eb3aedab3359d').should == 'new value'
24
+ Air18n::PhraseRevision.value_from_hash('revisions key', '5d10ab09a3cd6e0227c2c79fd8e525b7').should == 'second value'
25
+ end
26
+
27
+ it 'should copy over existing translations' do
28
+ # Create an old phrase that we don't want to copy the translations of.
29
+ @phrase0 = FactoryGirl.create(:phrase, :key => 'copying, key 0', :value => 'copying, value 1')
30
+ FactoryGirl.create(:phrase_translation,
31
+ :phrase => @phrase0,
32
+ :value => 'copying, old Traditional Chinese value 1',
33
+ :locale => :"zh-TW")
34
+
35
+ # Create a phrase that we do want to copy the translations of.
36
+ @phrase1 = FactoryGirl.create(:phrase, :key => 'copying, key 1', :value => 'copying, value 1')
37
+ FactoryGirl.create(:phrase_translation,
38
+ :phrase => @phrase1,
39
+ :value => 'copying, Simplified Chinese value 1',
40
+ :locale => :"zh")
41
+ FactoryGirl.create(:phrase_translation,
42
+ :phrase => @phrase1,
43
+ :value => 'copying, Traditional Chinese value 1',
44
+ :locale => :"zh-TW")
45
+ FactoryGirl.create(:phrase_translation,
46
+ :phrase => @phrase1,
47
+ :value => 'copying, French value 1',
48
+ :locale => :fr)
49
+
50
+ # Create a phrase with the same default text.
51
+ @phrase2 = FactoryGirl.create(:phrase, :key => 'copying, key 2', :value => 'copying, value 1')
52
+
53
+ # Should have three translations auto-populated.
54
+ @phrase2.phrase_translations.size.should == 3
55
+
56
+ @phrase2.latest_translation(:"zh-TW").id.should < @phrase2.latest_translation(:zh).id
25
57
  end
26
58
  end
27
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: air18n
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-02-26 00:00:00.000000000 Z
16
+ date: 2013-03-25 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: i18n