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.
- data/lib/air18n/backend.rb +5 -1
- data/lib/air18n/phrase.rb +48 -1
- data/lib/air18n/version.rb +1 -1
- data/spec/lib/air18n/backend_spec.rb +10 -0
- data/spec/lib/air18n/phrase_spec.rb +42 -10
- metadata +2 -2
data/lib/air18n/backend.rb
CHANGED
@@ -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)
|
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|
|
data/lib/air18n/phrase.rb
CHANGED
@@ -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 =>
|
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 = {}
|
data/lib/air18n/version.rb
CHANGED
@@ -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 '
|
7
|
-
it
|
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 =
|
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 ==
|
12
|
+
phrase.phrase_revisions.first.value_hash.should == '14979451a8c46ae1691eb3aedab3359d'
|
13
13
|
|
14
|
-
phrase.value =
|
14
|
+
phrase.value = 'second value'
|
15
15
|
phrase.save!
|
16
16
|
revisions = phrase.revisions_in_order
|
17
|
-
revisions.map(&:value_hash).should == [
|
17
|
+
revisions.map(&:value_hash).should == ['14979451a8c46ae1691eb3aedab3359d', '5d10ab09a3cd6e0227c2c79fd8e525b7']
|
18
18
|
|
19
|
-
phrase.value =
|
19
|
+
phrase.value = 'new value'
|
20
20
|
phrase.save!
|
21
21
|
revisions = phrase.revisions_in_order
|
22
|
-
revisions.map(&:value_hash).should == [
|
23
|
-
Air18n::PhraseRevision.value_from_hash('revisions key',
|
24
|
-
Air18n::PhraseRevision.value_from_hash('revisions key',
|
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.
|
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-
|
16
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: i18n
|