grosser-fast_gettext 0.4.8 → 0.4.9

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -6,6 +6,7 @@ It supports multiple backends (atm: .mo files, .po files, Database(ActiveRecor +
6
6
 
7
7
  [Example Rails application](https://github.com/grosser/gettext_i18n_rails_example)
8
8
 
9
+
9
10
  Setup
10
11
  =====
11
12
  ### 1. Install
@@ -17,13 +18,14 @@ Or from source:
17
18
 
18
19
  ### 2. Add a translation repository
19
20
 
20
- #### From mo files (traditional/default)
21
+ From mo files (traditional/default)
21
22
  FastGettext.add_text_domain('my_app',:path=>'locale')
22
23
 
23
- #### po files (less maintenacnce than mo)
24
+ Or po files (less maintenacnce than mo)
24
25
  FastGettext.add_text_domain('my_app',:path=>'locale', :type=>:po)
25
26
 
26
- #### Database (odern/scaleable)
27
+ Or database (scaleable, great for many locales/translators)
28
+ require "fast_gettext/translation_repository/db"
27
29
  include FastGettext::TranslationRepository::Db.require_models #load and include default models
28
30
  FastGettext.add_text_domain('my_app', :type=>:db, :model=>TranslationKey)
29
31
 
@@ -40,13 +42,13 @@ Do this once in every Thread. (e.g. Rails -> ApplicationController)
40
42
  s_('Namespace|no-found') == 'not-found'
41
43
  n_('Axis','Axis',3) == 'Achsen' #German plural of Axis
42
44
 
45
+
43
46
  Managing translations
44
47
  ============
45
48
  ### mo/po-files
46
49
  Generate .po or .mo files using GetText parser (example tasks at [gettext_i18n_rails](http://github.com/grosser/gettext_i18n_rails))
47
50
 
48
- Tell Gettext where your .mo or .po files lie:
49
- #e.g. for locale/de/my_app.po and locale/de/LC_MESSAGES/my_app.mo
51
+ Tell Gettext where your .mo or .po files lie, e.g. for locale/de/my_app.po and locale/de/LC_MESSAGES/my_app.mo
50
52
  FastGettext.add_text_domain('my_app',:path=>'locale')
51
53
 
52
54
  Use the [original GetText](http://github.com/mutoh/gettext) to create and manage po/mo-files.
@@ -62,6 +64,7 @@ If you want to use your own models, have a look at the [default models](http://g
62
64
 
63
65
  To manage translations via a Web GUI, use a [Rails application and the translation_db_engine](http://github.com/grosser/translation_db_engine)
64
66
 
67
+
65
68
  Performance
66
69
  ===========
67
70
  50_000 translations speed / memory
@@ -82,6 +85,7 @@ small translation file <-> large translation file
82
85
  ActiveSupport I18n::Backend::Simple :
83
86
  21.770000s / 10100K <->
84
87
 
88
+
85
89
  Rails
86
90
  =======================
87
91
  Try the [gettext_i18n_rails plugin](http://github.com/grosser/gettext_i18n_rails), it simplifies the setup.
@@ -106,6 +110,7 @@ since it runs in a different thread then e.g. controllers, so set them inside yo
106
110
  session[:locale] = I18n.locale = FastGettext.set_locale(params[:locale] || session[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')
107
111
  end
108
112
 
113
+
109
114
  Advanced features
110
115
  =================
111
116
  ###Abnormal pluralisation
@@ -121,7 +126,7 @@ If the simple rule of "first `availble_locale` or 'en'" is not suficcient for yo
121
126
 
122
127
  ###Chains
123
128
  You can use any number of repositories to find a translation. Simply add them to a chain and when
124
- the first cannot translate a given msgid, the next is asked and so forth.
129
+ the first cannot translate a given key, the next is asked and so forth.
125
130
  repos = [
126
131
  FastGettext::TranslationRepository.build('new', :path=>'....'),
127
132
  FastGettext::TranslationRepository.build('old', :path=>'....')
@@ -132,11 +137,11 @@ the first cannot translate a given msgid, the next is asked and so forth.
132
137
  When you want to know which keys could not be translated or were used, add a Logger to a Chain:
133
138
  repos = [
134
139
  FastGettext::TranslationRepository.build('app', :path=>'....')
135
- FastGettext::TranslationRepository.build('logger', :type=>:logger, :callback=>lamda{|msgid_or_array_of_ids| ... }),
140
+ FastGettext::TranslationRepository.build('logger', :type=>:logger, :callback=>lamda{|key_or_array_of_ids| ... }),
136
141
  }
137
142
  FastGettext.add_text_domain 'combined', :type=>:chain, :chain=>repos
138
143
  If the Logger is in position #1 it will see all translations, if it is in position #2 it will only see the unfound.
139
- Unfound may not always mean missing, if you chose not to translate a word because the msgid is a good translation, it will appear nevertheless.
144
+ Unfound may not always mean missing, if you chose not to translate a word because the key is a good translation, it will appear nevertheless.
140
145
  A lambda or anything that responds to `call` will do as callback. A good starting point may be `examples/missing_translations_logger.rb`.
141
146
 
142
147
  ###Plugins
@@ -146,23 +151,22 @@ Write your own TranslationRepository!
146
151
  module FastGettext
147
152
  module TranslationRepository
148
153
  class Wtf
149
- define initialize(name,options), [key], plural(*msgids) and
154
+ define initialize(name,options), [key], plural(*keys) and
150
155
  either inherit from TranslationRepository::Base or define available_locales and pluralisation_rule
151
156
  end
152
157
  end
153
158
  end
154
159
 
160
+
155
161
  FAQ
156
162
  ===
157
163
  - [Problems with ActiveRecord messages?](http://wiki.github.com/grosser/fast_gettext/activerecord)
158
164
 
165
+
159
166
  TODO
160
167
  ====
161
- - add caching to untranslateable calls
162
- - break with gettext naming-tradition, convert msgid => key, msgstr => translation
163
- - some cleanup required, repositories should not have locale
164
- - use `default_locale=(x)` internally, atm the default is available_locales.first || 'en'
165
- - use `default_text_domain=(x)` internally, atm default is nil...
168
+ - YML backend that reads ActiveSupport::I18n files
169
+ - any ideas ? :D
166
170
 
167
171
  Author
168
172
  ======
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 4
4
- :patch: 8
4
+ :patch: 9
@@ -68,10 +68,20 @@ module FastGettext
68
68
  end
69
69
 
70
70
  def key_exist?(key)
71
- false
72
- translation = current_repository[key]
73
- current_cache[key] ||= translation
74
- !!translation
71
+ !!(cached_find key)
72
+ end
73
+
74
+ def cached_find(key)
75
+ translation = current_cache[key]
76
+ return translation if translation or translation == false #found or was not found before
77
+ current_cache[key] = current_repository[key] || false
78
+ end
79
+
80
+ def cached_plural_find(*keys)
81
+ key = '||||' + keys * '||||'
82
+ translation = current_cache[key]
83
+ return translation if translation or translation == false #found or was not found before
84
+ current_cache[key] = current_repository.plural(*keys) || false
75
85
  end
76
86
 
77
87
  def locale
@@ -17,33 +17,27 @@ module FastGettext
17
17
  klas.extend self
18
18
  end
19
19
 
20
- def _(translate)
21
- found = FastGettext.current_cache[translate] and return found
22
- FastGettext.current_cache[translate] = FastGettext.current_repository[translate] || translate
20
+ def _(key)
21
+ FastGettext.cached_find(key) or key
23
22
  end
24
23
 
25
24
  #translate pluralized
26
25
  # some languages have up to 4 plural forms...
27
26
  # n_(singular, plural, plural form 2, ..., count)
28
27
  # n_('apple','apples',3)
29
- def n_(*msgids)
30
- count = msgids.pop
31
- repo = FastGettext.current_repository
32
-
33
- translations = repo.plural(*msgids)
28
+ def n_(*keys)
29
+ count = keys.pop
30
+ translations = FastGettext.cached_plural_find *keys
34
31
  selected = FastGettext.pluralisation_rule.call(count)
35
32
  selected = selected ? 1 : 0 unless selected.is_a? Numeric #convert booleans to numbers
36
- translations[selected] || msgids[selected] || msgids.last
33
+ translations[selected] || keys[selected] || keys.last
37
34
  end
38
35
 
39
36
  #translate, but discard namespace if nothing was found
40
37
  # Car|Tire -> Tire if no translation could be found
41
38
  def s_(key,seperator=nil)
42
- if translation = FastGettext.current_cache[key] || FastGettext.current_repository[key]
43
- translation
44
- else
45
- key.split(seperator||NAMESPACE_SEPERATOR).last
46
- end
39
+ translation = FastGettext.cached_find(key) and return translation
40
+ key.split(seperator||NAMESPACE_SEPERATOR).last
47
41
  end
48
42
 
49
43
  #tell gettext: this string need translation (will be found during parsing)
@@ -52,8 +46,8 @@ module FastGettext
52
46
  end
53
47
 
54
48
  #tell gettext: this string need translation (will be found during parsing)
55
- def Nn_(*msgids)
56
- msgids
49
+ def Nn_(*keys)
50
+ keys
57
51
  end
58
52
  end
59
53
  end
@@ -4,8 +4,6 @@ module FastGettext
4
4
  # - base for all repositories
5
5
  # - fallback as empty repository, that cannot translate anything but does not crash
6
6
  class Base
7
- attr_accessor :locale
8
-
9
7
  def initialize(name,options={})
10
8
  @name = name
11
9
  @options = options
@@ -23,8 +21,8 @@ module FastGettext
23
21
  current_translations[key]
24
22
  end
25
23
 
26
- def plural(*msgids)
27
- current_translations.plural(*msgids)
24
+ def plural(*keys)
25
+ current_translations.plural(*keys)
28
26
  end
29
27
 
30
28
  protected
@@ -31,9 +31,9 @@ module FastGettext
31
31
  nil
32
32
  end
33
33
 
34
- def plural(*msgids)
34
+ def plural(*keys)
35
35
  chain.each do |c|
36
- result = c.plural(*msgids)
36
+ result = c.plural(*keys)
37
37
  return result unless result.compact.empty?
38
38
  end
39
39
  []
@@ -18,8 +18,8 @@ module FastGettext
18
18
  nil
19
19
  end
20
20
 
21
- def plural(*msgids)
22
- callback.call(msgids)
21
+ def plural(*keys)
22
+ callback.call(keys)
23
23
  []
24
24
  end
25
25
  end
@@ -180,7 +180,10 @@ describe 'Storage' do
180
180
  FastGettext.text_domain = 'xxx'
181
181
  FastGettext.available_locales = ['de','en']
182
182
  FastGettext.locale = 'de'
183
+ FastGettext.current_repository.stub!(:"[]").with('abc').and_return 'old'
184
+ FastGettext.current_repository.stub!(:"[]").with('unfound').and_return nil
183
185
  FastGettext._('abc')
186
+ FastGettext._('unfound')
184
187
  FastGettext.locale = 'en'
185
188
  end
186
189
 
@@ -198,19 +201,24 @@ describe 'Storage' do
198
201
  FastGettext.locale = 'de'
199
202
  FastGettext.text_domain = nil
200
203
  FastGettext.default_text_domain = 'xxx'
201
- FastGettext.current_cache['abc'].should == 'abc'
204
+ FastGettext.current_cache['abc'].should == 'old'
202
205
  end
203
206
 
204
207
  it "cache is restored through setting of default_locale" do
205
208
  FastGettext.send(:_locale=,nil)#reset locale to nil
206
209
  FastGettext.default_locale = 'de'
207
210
  FastGettext.locale.should == 'de'
208
- FastGettext.current_cache['abc'].should == 'abc'
211
+ FastGettext.current_cache['abc'].should == 'old'
209
212
  end
210
213
 
211
214
  it "stores a translation permanently" do
212
215
  FastGettext.locale = 'de'
213
- FastGettext.current_cache['abc'].should == 'abc'
216
+ FastGettext.current_cache['abc'].should == 'old'
217
+ end
218
+
219
+ it "stores a unfound translation permanently" do
220
+ FastGettext.locale = 'de'
221
+ FastGettext.current_cache['unfound'].should == false
214
222
  end
215
223
  end
216
224
 
@@ -221,8 +229,8 @@ describe 'Storage' do
221
229
  end
222
230
 
223
231
  it "finds using the current repository" do
224
- should_receive(:current_repository).and_return 'xxx'=>'1'
225
- key_exist?('xxx').should == true
232
+ should_receive(:current_repository).and_return '1234'=>'1'
233
+ key_exist?('1234').should == true
226
234
  end
227
235
 
228
236
  it "sets the current cache with a found result" do
@@ -233,7 +241,7 @@ describe 'Storage' do
233
241
 
234
242
  it "does not overwrite an existing cache value" do
235
243
  current_cache['xxx']='xxx'
236
- should_receive(:current_repository).and_return 'xxx'=>'1'
244
+ stub!(:current_repository).and_return 'xxx'=>'1'
237
245
  key_exist?('xxx')
238
246
  current_cache['xxx'].should == 'xxx'
239
247
  end
@@ -6,15 +6,16 @@ describe 'FastGettext::TranslationRepository::Base' do
6
6
  before do
7
7
  @rep = FastGettext::TranslationRepository::Base.new('x')
8
8
  end
9
+
9
10
  it "can be built" do
10
11
  @rep.available_locales.should == []
11
12
  end
13
+
12
14
  it "cannot translate" do
13
- @rep.locale = 'de'
14
15
  @rep['car'].should == nil
15
16
  end
17
+
16
18
  it "cannot pluralize" do
17
- @rep.locale = 'de'
18
19
  @rep.plural('Axis','Axis').should == ['Axis','Axis']
19
20
  end
20
21
  end
@@ -27,7 +27,7 @@ describe FastGettext::Translation do
27
27
  it "translates simple text" do
28
28
  _('car').should == 'Auto'
29
29
  end
30
- it "returns msgid if not translation was found" do
30
+ it "returns key if not translation was found" do
31
31
  _('NOT|FOUND').should == 'NOT|FOUND'
32
32
  end
33
33
  end
@@ -60,12 +60,12 @@ describe FastGettext::Translation do
60
60
  end
61
61
  end
62
62
 
63
- it "returns the appropriate msgid if no translation was found" do
63
+ it "returns the appropriate key if no translation was found" do
64
64
  n_('NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND'
65
65
  n_('NOTFOUND','NOTFOUNDs',2).should == 'NOTFOUNDs'
66
66
  end
67
67
 
68
- it "returns the last msgid when no translation was found and msgids where to short" do
68
+ it "returns the last key when no translation was found and keys where to short" do
69
69
  FastGettext.pluralisation_rule = lambda{|x|4}
70
70
  n_('Apple','Apples',2).should == 'Apples'
71
71
  end
@@ -75,7 +75,7 @@ describe FastGettext::Translation do
75
75
  it "translates simple text" do
76
76
  _('car').should == 'Auto'
77
77
  end
78
- it "returns cleaned msgid if a translation was not found" do
78
+ it "returns cleaned key if a translation was not found" do
79
79
  s_("XXX|not found").should == "not found"
80
80
  end
81
81
  it "can use a custom seperator" do
@@ -84,13 +84,13 @@ describe FastGettext::Translation do
84
84
  end
85
85
 
86
86
  describe :N_ do
87
- it "returns the msgid" do
87
+ it "returns the key" do
88
88
  N_('XXXXX').should == 'XXXXX'
89
89
  end
90
90
  end
91
91
 
92
92
  describe :Nn_ do
93
- it "returns the msgids as array" do
93
+ it "returns the keys as array" do
94
94
  Nn_('X','Y').should == ['X','Y']
95
95
  end
96
96
  end
@@ -99,7 +99,12 @@ describe FastGettext::Translation do
99
99
  describe :cache_hit do
100
100
  before do
101
101
  FastGettext.translation_repositories.replace({})
102
+ #singular cache keys
102
103
  current_cache['xxx'] = '1'
104
+
105
+ #plural cache keys
106
+ current_cache['||||xxx'] = ['1','2']
107
+ current_cache['||||xxx||||yyy'] = ['1','2']
103
108
  end
104
109
 
105
110
  it "uses the cache when translating with _" do
@@ -109,6 +114,14 @@ describe FastGettext::Translation do
109
114
  it "uses the cache when translating with s_" do
110
115
  s_('xxx').should == '1'
111
116
  end
117
+
118
+ it "uses the cache when translating with n_" do
119
+ n_('xxx','yyy',1).should == '1'
120
+ end
121
+
122
+ it "uses the cache when translating with n_ and single argument" do
123
+ n_('xxx',1).should == '1'
124
+ end
112
125
  end
113
126
 
114
127
  it "caches different locales seperatly" do
data/vendor/string.rb CHANGED
@@ -30,7 +30,7 @@ rescue ArgumentError
30
30
  # with field type such as d(decimal), f(float), ...
31
31
  # "%<age>d, %<weight>.1f" % {:age => 10, :weight => 43.4} == "10 43.4"
32
32
  # This is the recommanded way for Ruby-GetText
33
- # because the translators can understand the meanings of the msgids easily.
33
+ # because the translators can understand the meanings of the keys easily.
34
34
  def %(args)
35
35
  if args.kind_of? Hash
36
36
  ret = dup
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grosser-fast_gettext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.4.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-10 00:00:00 -07:00
12
+ date: 2009-05-15 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15