i18n_routing 0.2.1

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/CHANGELOG.rdoc ADDED
@@ -0,0 +1,11 @@
1
+ 0.2.1 (Apr 09, 2010)
2
+
3
+ * Minor Rails3 modification, added gemspec and pushed gem on gemcutter
4
+
5
+ 0.2.0 (Apr 07, 2010)
6
+
7
+ * All specs pass for Rails2, including nested deep resources
8
+
9
+ 0.1.0 (Mar 22, 2010)
10
+
11
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Guillaume Luccisano - g-mai|: guillaume.luccisano
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,15 @@
1
+ = I18nRouting
2
+
3
+ I18n_routing is a plugin for Ruby on Rails that lets you easily translate your routes trough the I18n api included in Rails since version 2.2
4
+
5
+ All necessary informations are available on the wiki : http://wiki.github.com/kwi/i18n_routing/
6
+
7
+ Warning: The plugin is not currently running well with deep nesting resources for Rails3. This will be fixed soon
8
+
9
+ == TODO
10
+
11
+ * Do nested resources for Rails3
12
+ * Another bug fix ?
13
+
14
+
15
+ Copyright (c) 2010 Guillaume Luccisano - g-mai|: guillaume.luccisano, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'spec/rake/spectask'
4
+
5
+ spec_files = Rake::FileList["spec/**/*_spec.rb"]
6
+
7
+
8
+ desc "Run specs for current Rails version"
9
+ Spec::Rake::SpecTask.new do |t|
10
+ t.spec_files = spec_files
11
+ t.spec_opts = lambda {
12
+ @rails_spec_version ? ["-c -- rails_spec_version=#{@rails_spec_version}"] : ["-c"]
13
+ }
14
+ end
15
+
16
+ task :default => :spec
17
+
18
+ desc "Run Rails 2.x specs"
19
+ task :rails2_spec do
20
+ @rails_spec_version = 2
21
+ Rake::Task['spec'].invoke
22
+ end
23
+
24
+ desc "Run Rails 3.x specs"
25
+ task :rails3_spec do
26
+ @rails_spec_version = 3
27
+ Rake::Task['spec'].invoke
28
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require 'i18n_routing'
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ if Rails.version < '3'
3
+ require 'i18n_routing_rails2'
4
+ else
5
+ require 'i18n_routing_rails3'
6
+ end
@@ -0,0 +1,238 @@
1
+ # encoding: utf8
2
+
3
+ #
4
+ # WARNING : Old and dirty Rails 2.x code
5
+ # Need clean up and intensive refactoring
6
+ #
7
+
8
+ module ActionController
9
+ module Routing
10
+ class Route #:nodoc:
11
+
12
+ alias_method :mkd_initialize, :initialize
13
+ def initialize(segments = [], requirements = {}, conditions = {})
14
+ @glang = requirements.delete(:glang)
15
+ mkd_initialize(segments, requirements, conditions)
16
+ end
17
+
18
+ private
19
+ alias_method :mkd_generation_requirements, :generation_requirements
20
+ # Add locale requirements to ensure good route is used when using url_for
21
+ def generation_requirements
22
+ r = mkd_generation_requirements
23
+ if @glang and !r.blank?
24
+ r << " and I18n.locale == :#{@glang}"
25
+ end
26
+
27
+ return r
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ module ActionController
34
+ module Routing
35
+ class RouteSet #:nodoc:
36
+
37
+ attr :locales, true
38
+ attr :i18n_verbose, true
39
+
40
+ class Mapper
41
+ def localized(locales = I18n.available_locales, opts = {})
42
+ old_value = @set.locales
43
+ @set.locales = locales
44
+ @set.i18n_verbose ||= opts.delete(:verbose)
45
+ yield
46
+ ensure
47
+ @set.locales = old_value
48
+ end
49
+
50
+ end
51
+
52
+ class NamedRouteCollection #:nodoc:
53
+
54
+ alias_method :mkd_define_url_helper, :define_url_helper
55
+ def define_url_helper(route, name, kind, options)
56
+ gl = Thread.current[:globalized]
57
+
58
+ mkd_define_url_helper(route, name, kind, options)
59
+
60
+ if gl
61
+ selector = url_helper_name(name, kind)
62
+
63
+ rlang = if i = name.to_s.rindex("_#{gl}")
64
+ "#{selector.to_s[0, i]}_glang_#{gl}#{selector.to_s[i + "_#{gl}".size, selector.to_s.size]}"
65
+ elsif (gls = Thread.current[:globalized_s]) and i = name.to_s.rindex("_#{gls}")
66
+ "#{selector.to_s[0, i]}_glang_#{gls}#{selector.to_s[i + "_#{gls}".size, selector.to_s.size]}"
67
+ else
68
+ "glang_#{selector}"
69
+ end
70
+
71
+ # surcharge de l'helper
72
+ @module.module_eval <<-end_eval # We use module_eval to avoid leaks
73
+ alias_method :gl#{selector}, :#{selector}
74
+
75
+ def #{selector}(*args)
76
+ selector_g = '#{rlang}'.gsub('glang', I18n.locale.to_s).to_sym
77
+
78
+ #logger.debug "Call routes : #{selector} => \#{selector_g} (#{rlang}) "
79
+ #puts "Call routes : #{selector} => \#{selector_g} (#{rlang}) Found:\#{respond_to? selector_g and selector_g != :#{selector}}"
80
+ if respond_to? selector_g and selector_g != :#{selector}
81
+ send(selector_g, *args)
82
+ else
83
+ gl#{selector}(*args)
84
+ end
85
+ end
86
+ protected :gl#{selector}
87
+ end_eval
88
+
89
+ end
90
+ end
91
+ end
92
+
93
+ alias_method :gl_add_named_route, :add_named_route
94
+ def add_named_route(name, path, options = {}) #:nodoc:
95
+ if @locales and !path.blank? and !Thread.current[:i18n_no_named_localization]
96
+ #puts "ADD NAMED ROUTE : #{path}"
97
+ name = name.to_s
98
+
99
+ @locales.each do |l|
100
+ I18n.locale = l
101
+ nt = "#{l}_#{name}"
102
+ if nt != name and ((t = I18n.t(path.to_s, :scope => :named_routes_path, :default => path.to_s)) != path)
103
+ gl_add_named_route(nt, t, options.merge(:glang => l))
104
+ puts("[I18n] > localize %-10s: %40s (%s) => %s" % ['route', name, l, t]) if @i18n_verbose
105
+ end
106
+ end
107
+
108
+ old_v = Thread.current[:globalized]
109
+ Thread.current[:globalized] = true
110
+ gl_add_named_route(name, path, options)
111
+ Thread.current[:globalized] = old_v
112
+ return
113
+ end
114
+
115
+ gl_add_named_route(name, path, options)
116
+ end
117
+
118
+ end
119
+ end
120
+ end
121
+
122
+ module ActionController
123
+ module Resources
124
+ class Resource
125
+ alias_method :mkd_initialize, :initialize
126
+ def initialize(entities, options)
127
+ @real_path = options.delete(:real_path)
128
+ @real_path = @real_path.to_s.singularize if @real_path
129
+
130
+ mkd_initialize(entities, options)
131
+ end
132
+
133
+ def nesting_name_prefix
134
+ @real_path ? "#{shallow_name_prefix}#{@real_path}_" : "#{shallow_name_prefix}#{singular}_"
135
+ end
136
+
137
+ def nesting_path_prefix
138
+ @nesting_path_prefix ||= (@real_path ? "#{shallow_path_prefix}/#{path_segment}/:#{@real_path}_id" : "#{shallow_path_prefix}/#{path_segment}/:#{singular}_id")
139
+ end
140
+ end
141
+
142
+ def switch_globalized_state(state)
143
+ old_g = Thread.current[:globalized]
144
+ Thread.current[:globalized] = state
145
+ yield
146
+ Thread.current[:globalized] = old_g
147
+ end
148
+
149
+ def switch_no_named_localization(state)
150
+ old_g = Thread.current[:i18n_no_named_localization]
151
+ Thread.current[:i18n_no_named_localization] = state
152
+ yield
153
+ Thread.current[:i18n_no_named_localization] = old_g
154
+ end
155
+
156
+ def create_globalized_resources(type, namespace, *entities, &block)
157
+
158
+ Thread.current[:i18n_nested_deep] ||= 0
159
+ Thread.current[:i18n_nested_deep] += 1
160
+
161
+ if @set.locales
162
+ name = entities.dup.shift.to_s
163
+
164
+ options = entities.extract_options!
165
+ opts = options.dup
166
+
167
+ opts[:controller] ||= name
168
+
169
+ locales = @set.locales
170
+ translated = nil
171
+ localized(nil) do
172
+ locales.each do |l|
173
+ I18n.locale = l
174
+ nt = "#{l}_#{name}"
175
+ if nt != name and ((t = I18n.t(name, :scope => namespace, :default => name)) != name)
176
+ nt = "#{l}_#{name}"
177
+ opts[:as] = t
178
+ opts[:glang] = l
179
+ opts[:real_path] = opts[:singular] || name
180
+ localized([l]) do
181
+ translated = true
182
+ switch_no_named_localization(true) do
183
+ send(type, nt.to_sym, opts, &block)
184
+ end
185
+ end
186
+ puts("[I18n] > localize %-10s: %40s (%s) => %s" % [namespace, nt, l, t]) if @set.i18n_verbose
187
+ end
188
+ end
189
+
190
+ if Thread.current[:i18n_nested_deep] < 2
191
+ switch_no_named_localization(nil) do
192
+ switch_globalized_state(true) do
193
+ send(type, *(entities << options), &block)
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ else
200
+ send(type, *entities, &block)
201
+ end
202
+
203
+ Thread.current[:i18n_nested_deep] -= 1
204
+ end
205
+
206
+ alias_method :gl_resources, :resources
207
+ def resources(*entities, &block)
208
+ create_globalized_resources(:gl_resources, :resources, *entities, &block)
209
+ end
210
+
211
+ alias_method :gl_resource, :resource
212
+ def resource(*entities, &block)
213
+ create_globalized_resources(:gl_resource, :resource, *entities, &block)
214
+ end
215
+
216
+ private
217
+ alias_method :gl_action_options_for, :action_options_for
218
+ def action_options_for(action, resource, method = nil, resource_options = {})
219
+ opts = gl_action_options_for(action, resource, method, resource_options)
220
+
221
+ if Thread.current[:globalized]
222
+ Thread.current[:globalized] = resource.plural
223
+ if resource.uncountable?
224
+ Thread.current[:globalized] = resource.plural.to_s + '_index'
225
+ end
226
+ Thread.current[:globalized_s] = resource.singular
227
+ else
228
+ Thread.current[:globalized] = nil
229
+ Thread.current[:globalized_s] = nil
230
+ end
231
+ if resource.options[:glang]
232
+ opts[:glang] = resource.options[:glang]
233
+ end
234
+
235
+ opts
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,242 @@
1
+ # encoding: utf8
2
+ require 'rack/mount'
3
+ require 'action_dispatch'
4
+
5
+ module I18nRouting
6
+ module Mapper
7
+
8
+ private
9
+ # Localize a resources or a resource
10
+ def localized_resources(type = :resources, *resources, &block)
11
+ localizable_route = nil
12
+
13
+ if @locales
14
+ res = resources.clone
15
+
16
+ options = res.extract_options!
17
+ r = res.first
18
+ resource = type == :resource ? ActionDispatch::Routing::Mapper::SingletonResource.new(r, options) : ActionDispatch::Routing::Mapper::Resource.new(r, options)
19
+
20
+ # Check for translated resource
21
+ @locales.each do |locale|
22
+ I18n.locale = locale
23
+ localized_path = I18n.t(resource.name, :scope => type, :default => resource.name.to_s)
24
+
25
+ # A translated route exists :
26
+ if localized_path and localized_path != resource.name.to_s
27
+ puts("[I18n] > localize %-10s: %40s (%s) => %s" % [type, resource.name, locale, localized_path]) if @i18n_verbose
28
+ opts = options.dup
29
+ opts[:path] = localized_path.to_sym
30
+ opts[:controller] ||= r
31
+ opts[:constraints] = opts[:constraints] ? opts[:constraints].dup : {}
32
+ opts[:constraints][:i18n_locale] = locale.to_s
33
+ res = ["#{locale}_#{r}".to_sym, opts]
34
+
35
+ # Create the localized resource(s)
36
+ scope(:constraints => opts[:constraints]) do
37
+ localized(nil) do
38
+ send(type, *res, &block)
39
+ end
40
+ end
41
+
42
+ localizable_route = resource
43
+ end
44
+ end
45
+ end
46
+ return localizable_route
47
+ end
48
+
49
+ # Set if the next route creation will be a localied route or not
50
+ # If yes, localizable is a name, or a Mapper::Resource
51
+ # Can take a block, if so, save the current context, set the new
52
+ # Call the block, then restore the old context and return the block return
53
+ def set_localizable_route(localizable)
54
+ if block_given?
55
+ old = @set.named_routes.localizable
56
+ @set.named_routes.set_localizable_route(localizable)
57
+ r = yield
58
+ @set.named_routes.set_localizable_route(old)
59
+ return r
60
+ else
61
+ @set.named_routes.set_localizable_route(localizable)
62
+ end
63
+ end
64
+
65
+ public
66
+
67
+ # On Routing::Mapper initialization (when doing Application.routes.draw do ...)
68
+ # prepare routing system to be i18n ready
69
+ def initialize(*args)
70
+ super
71
+
72
+ # Add i18n as valid conditions for Rack::Mount
73
+ @valid_conditions = @set.instance_eval { @set }.instance_eval { @valid_conditions }
74
+ @valid_conditions << :i18n_locale if !@valid_conditions.include?(:i18n_locale)
75
+
76
+ # Extends the current RouteSet in order to define localized helper for named routes
77
+ # When calling define_url_helper, it calls define_localized_url_helper too.
78
+ if !@set.named_routes.respond_to?(:define_localized_url_helper)
79
+ @set.named_routes.class_eval <<-END_EVAL, __FILE__, __LINE__ + 1
80
+ alias_method :localized_define_url_helper, :define_url_helper
81
+ def define_url_helper(route, name, kind, options)
82
+ localized_define_url_helper(route, name, kind, options)
83
+ define_localized_url_helper(route, name, kind, options)
84
+ end
85
+ END_EVAL
86
+
87
+ @set.named_routes.extend I18nRouting::NamedRouteCollection
88
+ end
89
+ end
90
+
91
+ # Rails 3 routing system
92
+ # Create a block for localized routes, in your routes.rb :
93
+ #
94
+ # localized do
95
+ # resources :users
96
+ # match 'about' => 'contents#about', :as => :about
97
+ # end
98
+ #
99
+ def localized(locales = I18n.available_locales, opts = {})
100
+ old_value = @locales
101
+ @locales = locales
102
+ @i18n_verbose = opts.delete(:verbose)
103
+ yield
104
+ ensure
105
+ @locales = old_value
106
+ end
107
+
108
+ def match(*args)
109
+ # Localize simple match only if there is no resource scope.
110
+ if args.size == 1 and @locales and !@scope[:scope_level_resource] and args.first[:as]
111
+ @locales.each do |locale|
112
+ mapping = LocalizedMapping.new(locale, @set, @scope, Marshal.load(Marshal.dump(args))) # Dump is dirty but how to make deep cloning easily ? :/
113
+ if mapping.localizable?
114
+ puts("[I18n] > localize %-10s: %40s (%s) => %s" % ['route', args.first[:as], locale, mapping.path]) if @i18n_verbose
115
+ @set.add_route(*mapping.to_route)
116
+ end
117
+ end
118
+
119
+ # Now, create the real match :
120
+ return set_localizable_route(args.first[:as]) do
121
+ super
122
+ end
123
+ end
124
+
125
+ super
126
+ end
127
+
128
+ def resource(*resources, &block)
129
+ set_localizable_route(nil) do
130
+ set_localizable_route(localized_resources(:resource, *resources, &block))
131
+ super
132
+ end
133
+ end
134
+
135
+ def resources(*resources, &block)
136
+ set_localizable_route(nil) do
137
+ set_localizable_route(localized_resources(:resources, *resources, &block))
138
+ super
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ # Used for localize simple named routes
145
+ class LocalizedMapping < ActionDispatch::Routing::Mapper::Mapping
146
+
147
+ attr_reader :path
148
+
149
+ def initialize(locale, set, scope, args)
150
+ super(set, scope, args.clone)
151
+
152
+ # try to get translated path :
153
+ I18n.locale = locale
154
+ ts = @path.gsub(/^\//, '')
155
+ @localized_path = '/' + I18n.t(ts, :scope => :named_routes_path, :default => ts)
156
+
157
+ # If a translated path exists, set localized infos
158
+ if @localized_path and @localized_path != @path
159
+ #@options[:controller] ||= @options[:as]
160
+ @options[:as] = "#{locale}_#{@options[:as]}".to_sym
161
+ @path = @localized_path
162
+ @options[:constraints] = @options[:constraints] ? @options[:constraints].dup : {}
163
+ @options[:constraints][:i18n_locale] = locale.to_s
164
+ @options[:anchor] = true
165
+ else
166
+ @localized_path = nil
167
+ end
168
+
169
+ end
170
+
171
+ # Return true if this route is localizable
172
+ def localizable?
173
+ @localized_path != nil
174
+ end
175
+
176
+ end
177
+
178
+ module NamedRouteCollection
179
+
180
+ attr_reader :localizable
181
+
182
+ def set_localizable_route(localizable)
183
+ @localizable = localizable
184
+ end
185
+
186
+ # Alias named route helper in order to check if a localized helper exists
187
+ # If not use the standard one.
188
+ def define_localized_url_helper(route, name, kind, options)
189
+ if n = localizable
190
+ selector = url_helper_name(name, kind)
191
+
192
+ rlang = if n.kind_of?(ActionDispatch::Routing::Mapper::Resources::Resource) and i = name.to_s.rindex("_#{n.plural}")
193
+ "#{selector.to_s[0, i]}_glang_#{n.plural}#{selector.to_s[i + "_#{n.plural}".size, selector.to_s.size]}"
194
+ elsif n.kind_of?(ActionDispatch::Routing::Mapper::Resources::Resource) and i = name.to_s.rindex("_#{n.singular}")
195
+ "#{selector.to_s[0, i]}_glang_#{n.singular}#{selector.to_s[i + "_#{n.singular}".size, selector.to_s.size]}"
196
+ else
197
+ "glang_#{selector}"
198
+ end
199
+
200
+ @module.module_eval <<-end_eval # We use module_eval to avoid leaks
201
+ alias_method :localized_#{selector}, :#{selector}
202
+
203
+ def #{selector}(*args)
204
+ selector_g = '#{rlang}'.gsub('glang', I18n.locale.to_s).to_sym
205
+
206
+ #puts "Call routes : #{selector} => \#{selector_g} (\#{I18n.locale}) "
207
+ if respond_to? selector_g and selector_g != :#{selector}
208
+ send(selector_g, *args)
209
+ else
210
+ localized_#{selector}(*args)
211
+ end
212
+ end
213
+ end_eval
214
+
215
+ end
216
+ end
217
+ end
218
+
219
+ # Rack::Mount::Route module
220
+ # Exists in order to use apropriate localized route when using url_for
221
+ module RackMountRoute
222
+
223
+ # During route initialization, if a condition i18n_locale is present
224
+ # Delete it, and store it in @locale
225
+ def initialize(app, conditions, defaults, name)
226
+ @locale = conditions[:i18n_locale] ? conditions.delete(:i18n_locale).source.to_sym : nil
227
+ super
228
+ end
229
+
230
+ # Called for dynamic route generation
231
+ # If a @locale is present and if this locale is not the current one
232
+ # => return nil and refuse to generate the route
233
+ def generate(method, params = {}, recall = {}, options = {})
234
+ return nil if @locale and @locale != I18n.locale
235
+ super
236
+ end
237
+
238
+ end
239
+ end
240
+
241
+ ActionDispatch::Routing::Mapper.send :include, I18nRouting::Mapper
242
+ Rack::Mount::Route.send :include, I18nRouting::RackMountRoute
@@ -0,0 +1,202 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe :localized_routes do
4
+ before(:all) do
5
+
6
+ puts "Route for localize spec"
7
+ ActionController::Routing::Routes.clear!
8
+
9
+ if Rails.version < '3'
10
+
11
+ ActionController::Routing::Routes.draw do |map|
12
+ map.not_about 'not_about', :controller => 'not_about'
13
+ map.resources :not_users
14
+ map.resource :not_contact
15
+
16
+ map.localized do
17
+ map.about 'about', :controller => 'about', :action => :show
18
+
19
+ map.resources :users
20
+ map.resource :contact
21
+
22
+ map.resources :authors do |m|
23
+ m.resources :books
24
+ end
25
+
26
+ map.resources :universes do |m|
27
+ m.resources :galaxies do |mm|
28
+ mm.resources :planets
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ else
35
+
36
+ ActionController::Routing::Routes.draw do
37
+ match 'not_about' => "not_about#show", :as => :not_about
38
+ resources :not_users
39
+ resource :not_contact
40
+
41
+ localized(I18n.available_locales, :verbose => true) do
42
+ match 'about' => "about#show", :as => :about
43
+
44
+ resources :users
45
+ resource :contact
46
+
47
+ resources :authors do
48
+ resources :books
49
+ end
50
+
51
+ resources :universes do
52
+ resources :galaxies do
53
+ resources :planets
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+
63
+ class UrlTester
64
+ include ActionController::UrlWriter
65
+ end
66
+
67
+ @routes = UrlTester.new
68
+ end
69
+
70
+ def routes
71
+ @routes
72
+ end
73
+
74
+ def url_for(opts)
75
+ ActionController::Routing::Routes.generate_extras(opts).first
76
+ end
77
+
78
+ it "should still work for non localized named_route" do
79
+ routes.send(:not_about_path).should == "/not_about"
80
+ end
81
+
82
+ it "should still work for non localized resource" do
83
+ routes.send(:not_contact_path).should == "/not_contact"
84
+ end
85
+
86
+ it "should still work for non localized resources" do
87
+ routes.send(:not_users_path).should == "/not_users"
88
+ end
89
+
90
+ it "should works for localized named_route" do
91
+ I18n.locale = :fr
92
+ routes.send(:about_path).should == "/#{I18n.t :about, :scope => :named_routes_path}"
93
+ I18n.locale = :en
94
+ routes.send(:about_path).should == "/#{I18n.t :about, :scope => :named_routes_path}"
95
+ I18n.locale = :de # Not localized
96
+ routes.send(:about_path).should == "/about"
97
+ end
98
+
99
+ it "should works for localized resource" do
100
+ I18n.locale = :fr
101
+ routes.send(:contact_path).should == "/#{I18n.t :contact, :scope => :resource}"
102
+ I18n.locale = :en
103
+ routes.send(:contact_path).should == "/#{I18n.t :contact, :scope => :resource}"
104
+ I18n.locale = :de # Not localized
105
+ routes.send(:contact_path).should == "/contact"
106
+ end
107
+
108
+ it "should works for localized resources" do
109
+ I18n.locale = :fr
110
+ routes.send(:users_path).should == "/#{I18n.t :users, :scope => :resources}"
111
+ I18n.locale = :en
112
+ routes.send(:users_path).should == "/#{I18n.t :users, :scope => :resources}"
113
+ I18n.locale = :de # Not localized
114
+ routes.send(:users_path).should == "/users"
115
+ end
116
+
117
+ it "should works with url_for" do
118
+ I18n.locale = :fr
119
+ url_for(:controller => :users).should == "/#{I18n.t :users, :scope => :resources}"
120
+ url_for(:controller => :about, :action => :show).should == "/#{I18n.t :about, :scope => :named_routes_path}"
121
+ I18n.locale = :en
122
+ url_for(:controller => :users).should == "/#{I18n.t :users, :scope => :resources}"
123
+ I18n.locale = :de # Not localized
124
+ url_for(:controller => :users).should == "/users"
125
+ end
126
+
127
+ it "should have correct controller requirements" do
128
+
129
+ end
130
+
131
+ it "should main resources works with nested resources" do
132
+ I18n.locale = :fr
133
+ routes.send(:authors_path).should == "/#{I18n.t :authors, :scope => :resources}"
134
+ I18n.locale = :de # Not localized
135
+ routes.send(:authors_path).should == "/authors"
136
+ end
137
+
138
+ it "should works with nested resources" do
139
+ I18n.locale = :fr
140
+ routes.send(:author_books_path, 1).should == "/#{I18n.t :authors, :scope => :resources}/1/#{I18n.t :books, :scope => :resources}"
141
+ I18n.locale = :de # Not localized
142
+ routes.send(:author_books_path, 1).should == "/authors/1/books"
143
+ end
144
+
145
+ it "should works with deep nested resources" do
146
+ I18n.locale = :fr
147
+ routes.send(:universes_path).should == "/#{I18n.t :universes, :scope => :resources}"
148
+ routes.send(:universe_galaxies_path, 1).should == "/#{I18n.t :universes, :scope => :resources}/1/#{I18n.t :galaxies, :scope => :resources}"
149
+ routes.send(:universe_galaxy_planets_path, 1, 1).should == "/#{I18n.t :universes, :scope => :resources}/1/#{I18n.t :galaxies, :scope => :resources}/1/#{I18n.t :planets, :scope => :resources}"
150
+ I18n.locale = :de # Not localized
151
+ routes.send(:universes_path).should == "/universes"
152
+ routes.send(:universe_galaxies_path, 1).should == "/universes/1/galaxies"
153
+ routes.send(:universe_galaxy_planets_path, 1, 1).should == "/universes/1/galaxies/1/planets"
154
+ end
155
+
156
+ it "should nested resources have correct significant_keys" do
157
+ r = ActionController::Routing::Routes.named_routes.instance_eval { @routes }
158
+ #puts r.keys.to_yaml
159
+
160
+ r[:author_fr_books].should_not be_nil
161
+
162
+ if Rails.version < '3'
163
+ r[:author_books].significant_keys.should include(:author_id)
164
+ r[:author_fr_books].significant_keys.should include(:author_id)
165
+ else
166
+ r[:author_books].segment_keys.should include(:author_id)
167
+ r[:author_fr_books].segment_keys.should include(:author_id)
168
+ end
169
+ end
170
+
171
+ it "should deep nested resources have correct significant_keys" do
172
+ r = ActionController::Routing::Routes.named_routes.instance_eval { @routes }
173
+ #puts r.keys.to_yaml
174
+
175
+ r[:universe_galaxy_fr_planet].should_not be_nil
176
+
177
+ if Rails.version < '3'
178
+ r[:universe_galaxy_planet].significant_keys.should include(:universe_id)
179
+ r[:universe_galaxy_fr_planet].significant_keys.should include(:universe_id)
180
+ r[:universe_galaxy_planet].significant_keys.should include(:galaxy_id)
181
+ r[:universe_galaxy_fr_planet].significant_keys.should include(:galaxy_id)
182
+ else
183
+ r[:universe_galaxy_planet].segment_keys.should include(:universe_id)
184
+ r[:universe_galaxy_fr_planet].segment_keys.should include(:universe_id)
185
+ r[:universe_galaxy_planet].segment_keys.should include(:galaxy_id)
186
+ r[:universe_galaxy_fr_planet].segment_keys.should include(:galaxy_id)
187
+ end
188
+ end
189
+
190
+ it "should nested resources not deep translate with multi helpers" do
191
+ r = ActionController::Routing::Routes.named_routes.instance_eval { @routes }
192
+
193
+ r.keys.should_not include(:fr_author_books) # Whant fr_author_books
194
+ end
195
+
196
+ # it "zZ Just print routes :)" do
197
+ # r = ActionController::Routing::Routes.named_routes.instance_eval { @routes }
198
+ # puts r.keys.collect(&:to_s).sort.to_yaml
199
+ # puts "Nb Routes : #{r.keys.size}"
200
+ # end
201
+
202
+ end
@@ -0,0 +1,11 @@
1
+ en:
2
+ resources:
3
+ users: members
4
+ authors: 'authors-en'
5
+ galaxies: 'galaxies-en'
6
+ planets: 'planets-en'
7
+ universes: 'universes-en'
8
+ resource:
9
+ contact: 'contact-us'
10
+ named_routes_path:
11
+ about: 'about-our-company'
@@ -0,0 +1,13 @@
1
+ fr:
2
+ resources:
3
+ users: utilisateurs
4
+ authors: 'auteurs'
5
+ books: 'livres'
6
+ galaxies: 'galaxies-en-francais'
7
+ planets: 'planetes'
8
+ universes: 'univers'
9
+ resource:
10
+ contact: 'contactez-nous'
11
+ named_routes_path:
12
+ about: 'a-propos'
13
+
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $rails_version = ARGV.find { |e| e =~ /rails_spec_version=.*/ }.split('=').last.to_i rescue nil
5
+
6
+ if !$rails_version
7
+ begin
8
+ require 'rails'
9
+ rescue Exception
10
+ $rails_version = 2
11
+ end
12
+ end
13
+
14
+ if !Module.constants.include?('Rails') and $rails_version
15
+ module Rails
16
+ def self.version
17
+ $rails_version.to_s
18
+ end
19
+ end
20
+ end
21
+
22
+ if Rails.version < '3'
23
+ gem 'actionpack', '< 2.9.9'
24
+ require 'action_controller'
25
+ require 'action_controller/routing'
26
+ else
27
+ gem 'actionpack', '> 2.9'
28
+ require 'action_controller'
29
+ require 'rack/mount'
30
+ end
31
+
32
+ puts "Launching spec for Rails #{Rails.version}"
33
+
34
+ # Add I18n load_path
35
+ I18n.load_path = (I18n.load_path << Dir[File.join(File.dirname(__FILE__), 'locales', '*.yml')]).uniq
36
+
37
+ require File.dirname(__FILE__) + '/../init.rb'
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: i18n_routing
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 1
9
+ version: 0.2.1
10
+ platform: ruby
11
+ authors:
12
+ - Guillaume Luccisano
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-09 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: I18n_routing is a plugin for Ruby on Rails that lets you easily translate your routes trough the I18n api included in Rails since version 2.2
22
+ email: guillaume.luccisano@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/i18n_routing.rb
31
+ - lib/i18n_routing_rails2.rb
32
+ - lib/i18n_routing_rails3.rb
33
+ - spec/i18n_routing/i18n_spec.rb
34
+ - spec/locales/en.yml
35
+ - spec/locales/fr.yml
36
+ - spec/spec_helper.rb
37
+ - CHANGELOG.rdoc
38
+ - MIT-LICENSE
39
+ - Rakefile
40
+ - README.rdoc
41
+ - init.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/kwi/i18n_routing
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ segments:
63
+ - 1
64
+ - 3
65
+ - 4
66
+ version: 1.3.4
67
+ requirements: []
68
+
69
+ rubyforge_project: i18n_routing
70
+ rubygems_version: 1.3.6
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: I18n routing module for Rails 2.3.x and Rails 3. Translate your routes with ease !
74
+ test_files: []
75
+