i18n_routing 0.2.1

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