air18n 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|