i18n_multisite 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,51 @@
1
+ .rbenv-version
2
+
3
+ Gemfile.lock
4
+ # rcov generated
5
+ coverage
6
+
7
+ # rdoc generated
8
+ rdoc
9
+
10
+ # yard generated
11
+ doc
12
+ .yardoc
13
+
14
+ # bundler
15
+ .bundle
16
+
17
+ # jeweler generated
18
+ pkg
19
+
20
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
21
+ #
22
+ # * Create a file at ~/.gitignore
23
+ # * Include files you want ignored
24
+ # * Run: git config --global core.excludesfile ~/.gitignore
25
+ #
26
+ # After doing this, these files will be ignored in all your git projects,
27
+ # saving you from having to 'pollute' every project you touch with them
28
+ #
29
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
30
+ #
31
+ # For MacOS:
32
+ #
33
+ #.DS_Store
34
+
35
+ # For TextMate
36
+ #*.tmproj
37
+ #tmtags
38
+
39
+ # For emacs:
40
+ #*~
41
+ #\#*
42
+ #.\#*
43
+
44
+ # For vim:
45
+ #*.swp
46
+
47
+ # For redcar:
48
+ #.redcar
49
+
50
+ # For rubinius:
51
+ #*.rbc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+ gem "rspec"
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Mikhail Mikhaliov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,22 @@
1
+ = i18n_multisite
2
+
3
+ Support namespaces in *I18n* *Simple* backend
4
+
5
+ With a namespace set, these are the lookup keys
6
+
7
+ I18n.namespace = :site1
8
+
9
+ will be search these keys:
10
+ * site1.home.index.content
11
+ * home.index.content
12
+
13
+ t('home.index.content')
14
+
15
+ Your namespace can be an array too
16
+
17
+ I18n.namespace = [:main_site, :child_site]
18
+
19
+ will be search these keys:
20
+ * main_site.child_site.home.index.content
21
+ * main_site.home.index.content
22
+ * home.index.content
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new("spec")
7
+
8
+ task :default => :spec
9
+
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "i18n_multisite/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "i18n_multisite"
8
+ s.version = I18nMultisite::VERSION
9
+
10
+ s.authors = ["Mikhail Mikhaliov"]
11
+ s.email = ["legiar@gmail.com"]
12
+ s.description = "Support namespaces in I18n Simple backend"
13
+ s.summary = "Support namespaces in I18n Simple backend"
14
+ s.homepage = "http://github.com/legiar/i18n_multisite"
15
+ s.licenses = ["MIT"]
16
+
17
+ s.files = `git ls-files`.split($\)
18
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
19
+
20
+ s.add_dependency "rails", ">= 3"
21
+ s.add_development_dependency "rspec", ">= 2.0.0"
22
+ s.add_development_dependency "rspec-rails", ">= 2.0.0"
23
+ end
24
+
data/lib/ext/i18n.rb ADDED
@@ -0,0 +1,37 @@
1
+ require "i18n"
2
+
3
+ module I18n
4
+
5
+ class Config
6
+ attr_accessor :namespace
7
+ end
8
+
9
+ class << self
10
+
11
+ def namespace
12
+ config.namespace
13
+ end
14
+
15
+ def namespace=(value)
16
+ raise "Namespace contains unsupported objects. Allowed are: String, Symbol, Array[Symbol, String] or NilClass. Inspection: #{ns.inspect}" unless valid_namespace?(value)
17
+ config.namespace = value
18
+ end
19
+
20
+ private
21
+
22
+ def valid_namespace?(value)
23
+ case value
24
+ when String, Symbol, NilClass
25
+ true
26
+ when Array
27
+ return false if value.select(&:blank?).present?
28
+ return false if value.select{|item| ![String, Symbol].include?(item.class)}.present?
29
+ true
30
+ else
31
+ false
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,6 @@
1
+ require "active_support/core_ext"
2
+ require "ext/i18n"
3
+ require "i18n_multisite/version"
4
+ require "i18n_multisite/fallbacks"
5
+
6
+ I18n::Backend::Simple.send :include, I18nMultisite::Fallbacks
@@ -0,0 +1,37 @@
1
+ module I18nMultisite
2
+
3
+ module Fallbacks
4
+
5
+ def translate(locale, key, options = {})
6
+ return super if ::I18n.namespace.blank?
7
+ default = extract_non_symbol_default!(options) if options[:default]
8
+
9
+ scope = Array.wrap(options.delete(:scope))
10
+ namespace = Array.wrap(::I18n.namespace)
11
+
12
+ (namespace.size + 1).times do |part|
13
+ catch(:exception) do
14
+ options[:scope] = (namespace | scope).reject(&:nil?)
15
+
16
+ result = super(locale, key, options)
17
+ result = super(locale, nil, options.merge(:default => default)) if result.nil? && default
18
+ return result unless result.nil?
19
+ end
20
+ namespace.pop
21
+ end
22
+
23
+ return super(locale, nil, options.merge(:default => default)) if default
24
+ throw(:exception, ::I18n::MissingTranslation.new(locale, key, options))
25
+ end
26
+
27
+ def extract_non_symbol_default!(options)
28
+ defaults = [options[:default]].flatten
29
+ first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)}
30
+ if first_non_symbol_default
31
+ options[:default] = defaults[0, defaults.index(first_non_symbol_default)]
32
+ end
33
+ return first_non_symbol_default
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module I18nMultisite
2
+ VERSION = "0.0.5"
3
+ end
@@ -0,0 +1,254 @@
1
+ require "spec_helper"
2
+ require "i18n"
3
+ require "i18n_multisite"
4
+
5
+ describe I18n do
6
+
7
+ before :all do
8
+ I18n.backend = I18n::Backend::Simple.new()
9
+ end
10
+
11
+ before :each do
12
+ I18n.namespace = nil
13
+ I18n.reload!
14
+ end
15
+
16
+ def t(key, options = {})
17
+ I18n.t key, options
18
+ end
19
+
20
+ def s(data, options = {})
21
+ I18n.backend.store_translations I18n.locale, data, options
22
+ end
23
+
24
+ def sr(key, value)
25
+ I18n.store_resolved_translation I18n.locale, key, value
26
+ end
27
+
28
+ def store_translations(*args)
29
+ case args.count
30
+ when 1
31
+ raise "Your argument isn't a Hash" unless args.first.is_a? Hash
32
+ data = args.shift
33
+ when 2
34
+ data = { args.shift => args.shift }
35
+ end
36
+
37
+ I18n.backend.store_translations I18n.locale, data
38
+ end
39
+
40
+ describe "config" do
41
+
42
+ it "should has read accessor 'namespace'" do
43
+ I18n.config.should respond_to(:namespace)
44
+ end
45
+
46
+ it "should has write accessor 'namespace='" do
47
+ I18n.config.should respond_to('namespace=')
48
+ end
49
+
50
+ it "should has helper 'namespace'" do
51
+ I18n.should respond_to(:namespace)
52
+ end
53
+
54
+ it "should has helper 'namespace='" do
55
+ I18n.should respond_to('namespace=')
56
+ end
57
+
58
+ it "should has set namespace" do
59
+ I18n.namespace = :salesman
60
+ I18n.namespace.should eq :salesman
61
+ end
62
+
63
+ describe "validation" do
64
+ it "should raise if namespace array includes none supported objects" do
65
+ lambda { I18n.namespace = [ :salesman, nil ] }.should raise_error
66
+ lambda { I18n.namespace = [ :salesman, "" ] }.should raise_error
67
+
68
+ lambda { I18n.namespace = [ :salesman, Proc.new{} ] }.should raise_error
69
+ lambda { I18n.namespace = [ :salesman, Array.new ] }.should raise_error
70
+ lambda { I18n.namespace = [ :salesman, Hash.new ] }.should raise_error
71
+ end
72
+
73
+ it "should only accept String, Symbol, Array or NilClass" do
74
+ I18n.namespace = :symbol
75
+ I18n.namespace.should == :symbol
76
+
77
+ I18n.namespace = "string"
78
+ I18n.namespace.should == "string"
79
+
80
+ I18n.namespace = nil
81
+ I18n.namespace.should == nil
82
+
83
+ I18n.namespace = []
84
+ I18n.namespace.should == []
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ describe "namespace fallbacks" do
91
+
92
+ before :each do
93
+ @salesman_title = "Willkommen Salesman"
94
+ @club_title = "Willkommen im Club"
95
+ @title = "Willkommen"
96
+
97
+ store_translations({
98
+ :title => @title,
99
+ :salesman => {
100
+ :title => @salesman_title,
101
+ :club => {
102
+ :title => @club_title
103
+ }
104
+ }
105
+ })
106
+ end
107
+
108
+ describe "with no namespace" do
109
+
110
+ it "should return title" do
111
+ t("title").should == @title
112
+ end
113
+
114
+ it "should show translation missing" do
115
+ t("foobar").should include("translation missing")
116
+ end
117
+
118
+ end
119
+
120
+ describe "with namespace" do
121
+
122
+ it "should not fallback" do
123
+ I18n.namespace = :salesman
124
+ t("title").should == @salesman_title
125
+
126
+ I18n.namespace = [:salesman, :club]
127
+ t("title").should == @club_title
128
+ end
129
+
130
+ it "should fallback" do
131
+ I18n.namespace = [:salesman, :user]
132
+ t("title").should == @salesman_title
133
+
134
+ I18n.namespace = [:community, :user, "23051949"]
135
+ t("title").should == @title
136
+ end
137
+
138
+ it "should show translation missing" do
139
+ I18n.namespace = :salesman
140
+ t("foobar").should include("translation missing")
141
+ end
142
+ end
143
+
144
+ end
145
+
146
+ describe "with scope" do
147
+
148
+ before :each do
149
+ @message = "Base Message"
150
+ @site_message = "Message for site"
151
+
152
+
153
+ store_translations({
154
+ :activerecord => {
155
+ :errors => {
156
+ :messages => {
157
+ :record_invalid => @message
158
+ }
159
+ }
160
+ },
161
+ :site => {
162
+ :activerecord => {
163
+ :errors => {
164
+ :messages => {
165
+ :record_invalid => @site_message
166
+ }
167
+ }
168
+ }
169
+ }
170
+ })
171
+ end
172
+
173
+ it "should get base message" do
174
+ t(:record_invalid, :scope => [:activerecord, :errors, :messages]).should eq @message
175
+ end
176
+
177
+ it "should get scoped message" do
178
+ I18n.namespace = :site
179
+ t(:record_invalid, :scope => [:activerecord, :errors, :messages]).should eq @site_message
180
+ end
181
+
182
+ it "should get base message for fallback" do
183
+ I18n.namespace = :new_site
184
+ t(:record_invalid, :scope => [:activerecord, :errors, :messages]).should eq @message
185
+ end
186
+
187
+ end
188
+
189
+ describe "with defaults" do
190
+
191
+ # Class Admin < User
192
+ # end
193
+ #
194
+ # Admin.human_attribute_name(:name)
195
+ # try to find key: "activerecord.attributes.admin.name"
196
+ # with defaults:
197
+ # "activerecord.attributes.user.name"
198
+ # "attributes.name"
199
+ # "name"
200
+ before :each do
201
+ @admin_name = "Admin Name"
202
+ @user_title = "User Title"
203
+ @user_name = "User Name"
204
+
205
+ store_translations({
206
+ :activerecord => {
207
+ :attributes => {
208
+ :admin => {
209
+ :name => @admin_name
210
+ },
211
+ :user => {
212
+ :title => @user_title
213
+ }
214
+ }
215
+ },
216
+ :site => {
217
+ :activerecord => {
218
+ :attributes => {
219
+ :user => {
220
+ :name => @user_name
221
+ }
222
+ }
223
+ }
224
+ }
225
+ })
226
+
227
+ @name_default = [:"activerecord.attributes.user.name", :"attributes.name", :"name"]
228
+ @title_default = [:"activerecord.attributes.user.title", :"attributes.title", :"title"]
229
+ @name_key = "activerecord.attributes.admin.name"
230
+ @title_key = "activerecord.attributes.admin.title"
231
+ end
232
+
233
+ it "should get base message" do
234
+ I18n.t(@name_key, :namespaced => true, :default => @name_default).should eq @admin_name
235
+ end
236
+
237
+ it "should get message from defaults" do
238
+ I18n.t(@title_key, :namespaced => true, :default => @title_default, :count => 1).should eq @user_title
239
+ end
240
+
241
+ it "should get namespaced message from defaults" do
242
+ I18n.namespace = :site
243
+ I18n.t(@name_key, :namespaced => true, :default => @name_default, :count => 1).should eq @user_name
244
+ end
245
+
246
+ it "should get fallback message from defaults" do
247
+ I18n.namespace = :site
248
+ I18n.t(@title_key, :namespaced => true, :default => @title_default, :count => 1).should eq @user_title
249
+ end
250
+
251
+ end
252
+
253
+ end
254
+
@@ -0,0 +1,6 @@
1
+ RSpec.configure do |config|
2
+ config.treat_symbols_as_metadata_keys_with_true_values = true
3
+ config.run_all_when_everything_filtered = true
4
+ config.filter_run :focus
5
+ config.order = 'random'
6
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: i18n_multisite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mikhail Mikhaliov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.0.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.0.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec-rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 2.0.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.0
62
+ description: Support namespaces in I18n Simple backend
63
+ email:
64
+ - legiar@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .document
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.rdoc
75
+ - Rakefile
76
+ - i18n_multisite.gemspec
77
+ - lib/ext/i18n.rb
78
+ - lib/i18n_multisite.rb
79
+ - lib/i18n_multisite/fallbacks.rb
80
+ - lib/i18n_multisite/version.rb
81
+ - spec/lib/i18n_multisite_spec.rb
82
+ - spec/spec_helper.rb
83
+ homepage: http://github.com/legiar/i18n_multisite
84
+ licenses:
85
+ - MIT
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 1.8.24
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Support namespaces in I18n Simple backend
108
+ test_files:
109
+ - spec/lib/i18n_multisite_spec.rb
110
+ - spec/spec_helper.rb