i18n_multisite 0.0.5

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/.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