route_translator 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/route_translator.rb +10 -0
- data/lib/route_translator/railtie.rb +23 -0
- data/lib/route_translator/route_set.rb +16 -2
- data/lib/route_translator/route_set/translator.rb +23 -2
- data/lib/route_translator/routes_reloader.rb +15 -0
- data/lib/route_translator/test_request.rb +11 -0
- data/lib/route_translator/version.rb +1 -1
- data/test/route_translator_test.rb +97 -1
- data/test/test_helper.rb +44 -2
- metadata +23 -4
data/lib/route_translator.rb
CHANGED
@@ -2,7 +2,10 @@ require 'active_support'
|
|
2
2
|
require 'action_controller'
|
3
3
|
require 'action_mailer'
|
4
4
|
require 'action_dispatch'
|
5
|
+
|
5
6
|
require 'route_translator/route_set'
|
7
|
+
require 'route_translator/routes_reloader'
|
8
|
+
require 'route_translator/railtie' if defined?(Rails::Railtie)
|
6
9
|
|
7
10
|
module RouteTranslator
|
8
11
|
|
@@ -15,10 +18,16 @@ module RouteTranslator
|
|
15
18
|
ActionDispatch::Routing::UrlFor
|
16
19
|
].freeze
|
17
20
|
|
21
|
+
Configuration = Struct.new(:force_locale, :generate_unlocalized_routes, :translation_file)
|
22
|
+
|
18
23
|
def self.locale_suffix locale
|
19
24
|
locale.to_s.underscore
|
20
25
|
end
|
21
26
|
|
27
|
+
def self.config
|
28
|
+
@config ||= Configuration.new
|
29
|
+
end
|
30
|
+
|
22
31
|
# Attributes
|
23
32
|
|
24
33
|
module Controller
|
@@ -40,6 +49,7 @@ module RouteTranslator
|
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
52
|
+
ActiveSupport.run_load_hooks(:route_translator, self)
|
43
53
|
end
|
44
54
|
|
45
55
|
# Add locale_suffix to controllers, views and mailers
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RouteTranslator
|
2
|
+
class Railtie < ::Rails::Railtie
|
3
|
+
config.route_translator = ActiveSupport::OrderedOptions.new
|
4
|
+
|
5
|
+
initializer "route_translator.set_configs" do |app|
|
6
|
+
options = app.config.route_translator
|
7
|
+
options.force_locale ||= false
|
8
|
+
options.generate_unlocalized_routes ||= false
|
9
|
+
options.translation_file ||= File.join(%w[config i18n-routes.yml])
|
10
|
+
|
11
|
+
ActiveSupport.on_load :route_translator do
|
12
|
+
options.each do |k, v|
|
13
|
+
k = "#{k}="
|
14
|
+
if config.respond_to?(k)
|
15
|
+
config.send k, v
|
16
|
+
else
|
17
|
+
raise "Invalid option key: #{k}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -24,11 +24,25 @@ module RouteTranslator
|
|
24
24
|
|
25
25
|
#Use the translations from the specified file
|
26
26
|
def translate_from_file(file_path = nil)
|
27
|
-
file_path
|
28
|
-
|
27
|
+
file_path = absolute_path(file_path)
|
28
|
+
|
29
|
+
reset_dictionary
|
30
|
+
Dir[file_path].each do |file|
|
31
|
+
add_dictionary_from_file(file)
|
32
|
+
end
|
29
33
|
translate
|
30
34
|
end
|
31
35
|
|
36
|
+
private
|
37
|
+
|
38
|
+
def absolute_path (file_path)
|
39
|
+
file_path ||= RouteTranslator.config.translation_file
|
40
|
+
file_path = Rails.root.join(file_path) if defined?(Rails)
|
41
|
+
file_path
|
42
|
+
end
|
43
|
+
|
44
|
+
public
|
45
|
+
|
32
46
|
include Helpers
|
33
47
|
include Translator
|
34
48
|
include DictionaryManagement
|
@@ -10,9 +10,12 @@ module RouteTranslator
|
|
10
10
|
original_routes = routes.dup
|
11
11
|
original_named_routes = named_routes.routes.dup # Hash {:name => :route}
|
12
12
|
|
13
|
+
# The filter method exists if the "routing-filter" gem is used
|
14
|
+
original_filters = set.respond_to?(:filters) ? set.filters.dup : []
|
15
|
+
|
13
16
|
routes_to_create = []
|
14
17
|
original_routes.each do |original_route|
|
15
|
-
if localized_routes && localized_routes.include?(original_route.to_s)
|
18
|
+
if localized_routes && localized_routes.include?(original_route.to_s)
|
16
19
|
translations_for(original_route).each do |translated_route_args|
|
17
20
|
routes_to_create << translated_route_args
|
18
21
|
end
|
@@ -20,6 +23,11 @@ module RouteTranslator
|
|
20
23
|
route = untranslated_route original_route
|
21
24
|
routes_to_create << route
|
22
25
|
end
|
26
|
+
# Always generate unlocalized routes?
|
27
|
+
if RouteTranslator.config.generate_unlocalized_routes
|
28
|
+
route = untranslated_route original_route
|
29
|
+
routes_to_create << route
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
25
33
|
reset!
|
@@ -28,6 +36,10 @@ module RouteTranslator
|
|
28
36
|
add_route(*r)
|
29
37
|
end
|
30
38
|
|
39
|
+
if original_filters.any?
|
40
|
+
set.filters << original_filters
|
41
|
+
set.filters.flatten!
|
42
|
+
end
|
31
43
|
|
32
44
|
Hash[original_named_routes.select{|k,v| localized_routes && localized_routes.include?(v.to_s)}].each_key do |route_name|
|
33
45
|
named_routes.helpers.concat add_untranslated_helpers_to_controllers_and_views(route_name)
|
@@ -105,7 +117,16 @@ module RouteTranslator
|
|
105
117
|
def translate_path(path, locale)
|
106
118
|
final_optional_segments = path.slice!(/(\(.+\))$/)
|
107
119
|
new_path = path.split("/").map{|seg| translate_path_segment(seg, locale)}.join('/')
|
108
|
-
|
120
|
+
|
121
|
+
# Add locale prefix if it's not the default locale,
|
122
|
+
# or forcing locale to all routes,
|
123
|
+
# or already generating actual unlocalized routes
|
124
|
+
if !default_locale?(locale) ||
|
125
|
+
RouteTranslator.config.force_locale ||
|
126
|
+
RouteTranslator.config.generate_unlocalized_routes
|
127
|
+
new_path = "/#{locale.downcase}#{new_path}"
|
128
|
+
end
|
129
|
+
|
109
130
|
new_path = "/" if new_path.blank?
|
110
131
|
"#{new_path}#{final_optional_segments}"
|
111
132
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rails"
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
class Application
|
5
|
+
alias :reload_routes_without_translator! :reload_routes!
|
6
|
+
def reload_routes!
|
7
|
+
result = reload_routes_without_translator!
|
8
|
+
|
9
|
+
self.routes.default_locale = I18n.default_locale
|
10
|
+
self.routes.translate_from_file
|
11
|
+
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'mocha'
|
3
3
|
|
4
|
+
require "rails"
|
5
|
+
require "action_controller/railtie"
|
6
|
+
|
4
7
|
require 'route_translator'
|
8
|
+
require "route_translator/test_request"
|
5
9
|
|
6
10
|
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
7
11
|
|
8
|
-
|
9
12
|
class PeopleController < ActionController::Base; end
|
10
13
|
class ProductsController < ActionController::Base; end
|
11
14
|
|
@@ -17,12 +20,34 @@ class TranslateRoutesTest < ActionController::TestCase
|
|
17
20
|
I18n.default_locale = locale
|
18
21
|
end
|
19
22
|
|
23
|
+
def config_force_locale(boolean)
|
24
|
+
RouteTranslator.config.force_locale = boolean
|
25
|
+
end
|
26
|
+
|
27
|
+
def config_generate_unlocalized_routes(boolean)
|
28
|
+
RouteTranslator.config.generate_unlocalized_routes = boolean
|
29
|
+
end
|
30
|
+
|
31
|
+
def config_translation_file (file)
|
32
|
+
RouteTranslator.config.translation_file = file
|
33
|
+
end
|
34
|
+
|
20
35
|
def setup
|
36
|
+
setup_application
|
37
|
+
|
21
38
|
@controller = ActionController::Base.new
|
22
39
|
@view = ActionView::Base.new
|
23
40
|
@routes = ActionDispatch::Routing::RouteSet.new
|
24
41
|
end
|
25
42
|
|
43
|
+
def teardown
|
44
|
+
config_force_locale false
|
45
|
+
config_generate_unlocalized_routes false
|
46
|
+
config_default_locale_settings("en")
|
47
|
+
routes_file ""
|
48
|
+
FileUtils.rm_rf "#{tmp_path}/log"
|
49
|
+
end
|
50
|
+
|
26
51
|
def test_unnamed_root_route
|
27
52
|
@routes.draw do
|
28
53
|
localized do
|
@@ -313,6 +338,77 @@ class TranslateRoutesTest < ActionController::TestCase
|
|
313
338
|
assert_unrecognized_route '/es/productos', :controller => 'products', :action => 'index', :locale => 'es'
|
314
339
|
end
|
315
340
|
|
341
|
+
def test_force_locale
|
342
|
+
@routes.draw do
|
343
|
+
localized do
|
344
|
+
match 'people', :to => 'people#index', :as => 'people'
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
config_default_locale_settings 'en'
|
349
|
+
config_force_locale true
|
350
|
+
|
351
|
+
@routes.translate_from_file(File.expand_path('locales/routes.yml', File.dirname(__FILE__)))
|
352
|
+
|
353
|
+
assert_routing '/en/people', :controller => 'people', :action => 'index', :locale => 'en'
|
354
|
+
assert_unrecognized_route '/people', :controller => 'people', :action => 'index'
|
355
|
+
end
|
356
|
+
|
357
|
+
def test_generate_unlocalized_routes
|
358
|
+
@routes.draw do
|
359
|
+
localized do
|
360
|
+
match 'people', :to => 'people#index', :as => 'people'
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
config_default_locale_settings 'en'
|
365
|
+
config_generate_unlocalized_routes true
|
366
|
+
|
367
|
+
@routes.translate_from_file(File.expand_path('locales/routes.yml', File.dirname(__FILE__)))
|
368
|
+
|
369
|
+
assert_routing '/en/people', :controller => 'people', :action => 'index', :locale => 'en'
|
370
|
+
assert_routing '/people', :controller => 'people', :action => 'index'
|
371
|
+
end
|
372
|
+
|
373
|
+
def test_config_translation_file
|
374
|
+
@routes.draw do
|
375
|
+
localized do
|
376
|
+
root :to => 'people#index'
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
config_default_locale_settings 'es'
|
381
|
+
config_translation_file File.expand_path('locales/routes.yml', File.dirname(__FILE__))
|
382
|
+
|
383
|
+
@routes.translate_from_file
|
384
|
+
|
385
|
+
assert_routing '/', :controller => 'people', :action => 'index', :locale => 'es'
|
386
|
+
assert_routing '/en', :controller => 'people', :action => 'index', :locale => 'en'
|
387
|
+
assert_unrecognized_route '/es', :controller => 'people', :action => 'index', :locale => 'es'
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_auto_translate
|
391
|
+
|
392
|
+
routes_file <<-RUBY
|
393
|
+
Rails.application.routes.draw do
|
394
|
+
localized do
|
395
|
+
root :to => 'people#index'
|
396
|
+
end
|
397
|
+
end
|
398
|
+
RUBY
|
399
|
+
|
400
|
+
config_default_locale_settings 'es'
|
401
|
+
config_translation_file File.expand_path('locales/routes.yml', File.dirname(__FILE__))
|
402
|
+
|
403
|
+
app.reload_routes!
|
404
|
+
|
405
|
+
@routes = app.routes
|
406
|
+
|
407
|
+
assert_routing '/', :controller => 'people', :action => 'index', :locale => 'es'
|
408
|
+
assert_routing '/en', :controller => 'people', :action => 'index', :locale => 'en'
|
409
|
+
assert_unrecognized_route '/es', :controller => 'people', :action => 'index', :locale => 'es'
|
410
|
+
end
|
411
|
+
|
316
412
|
def test_action_controller_gets_locale_setter
|
317
413
|
ActionController::Base.instance_methods.include?('set_locale_from_url')
|
318
414
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
class StubbedI18nBackend
|
2
3
|
@@translations = {
|
3
4
|
'es' => { 'people' => 'gente'},
|
@@ -13,8 +14,6 @@ class StubbedI18nBackend
|
|
13
14
|
def self.available_locales
|
14
15
|
@@translations.keys
|
15
16
|
end
|
16
|
-
|
17
|
-
|
18
17
|
end
|
19
18
|
|
20
19
|
module RouteTranslator
|
@@ -32,6 +31,49 @@ module RouteTranslator
|
|
32
31
|
!(defined?(ActionPack) && ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR > 0)
|
33
32
|
end
|
34
33
|
|
34
|
+
def setup_application
|
35
|
+
return if defined?(@@app)
|
36
|
+
|
37
|
+
app = @@app = Class.new(Rails::Application)
|
38
|
+
app.config.active_support.deprecation = :stderr
|
39
|
+
app.paths["log"] = "#{tmp_path}/log/test.log"
|
40
|
+
app.initialize!
|
41
|
+
Rails.application = app
|
42
|
+
end
|
43
|
+
|
44
|
+
def app
|
45
|
+
@@app
|
46
|
+
end
|
47
|
+
|
48
|
+
def tmp_path(*args)
|
49
|
+
@tmp_path ||= File.join(File.dirname(__FILE__), "tmp")
|
50
|
+
File.join(@tmp_path, *args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def app_path(*args)
|
54
|
+
tmp_path(*%w[app] + args)
|
55
|
+
end
|
56
|
+
|
57
|
+
def routes_file(contents)
|
58
|
+
fn = File.join(app_path, routes_config)
|
59
|
+
FileUtils.mkdir_p File.dirname(fn)
|
60
|
+
File.open(fn, 'w') do |f|
|
61
|
+
f.puts contents
|
62
|
+
end
|
63
|
+
app.routes_reloader.paths.unshift(fn)
|
64
|
+
end
|
65
|
+
|
66
|
+
def routes_config
|
67
|
+
@@routes_config ||= File.join("config", "routes.rb")
|
68
|
+
end
|
69
|
+
|
70
|
+
def print_routes (route_set)
|
71
|
+
require 'rails/application/route_inspector'
|
72
|
+
inspector = Rails::Application::RouteInspector.new
|
73
|
+
puts inspector.format(route_set.routes, ENV['CONTROLLER']).join "\n"
|
74
|
+
rescue LoadError
|
75
|
+
end
|
76
|
+
|
35
77
|
def assert_helpers_include(*helpers)
|
36
78
|
helpers.each do |helper|
|
37
79
|
['url', 'path'].each do |suffix|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: route_translator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-10-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mocha
|
@@ -20,7 +20,23 @@ dependencies:
|
|
20
20
|
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '0'
|
23
|
-
type: :
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: guard-test
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :development
|
24
40
|
prerelease: false
|
25
41
|
version_requirements: !ruby/object:Gem::Requirement
|
26
42
|
none: false
|
@@ -36,10 +52,13 @@ extensions: []
|
|
36
52
|
extra_rdoc_files: []
|
37
53
|
files:
|
38
54
|
- lib/route_translator.rb
|
55
|
+
- lib/route_translator/railtie.rb
|
39
56
|
- lib/route_translator/route_set.rb
|
40
57
|
- lib/route_translator/route_set/dictionary_management.rb
|
41
58
|
- lib/route_translator/route_set/helpers.rb
|
42
59
|
- lib/route_translator/route_set/translator.rb
|
60
|
+
- lib/route_translator/routes_reloader.rb
|
61
|
+
- lib/route_translator/test_request.rb
|
43
62
|
- lib/route_translator/version.rb
|
44
63
|
- lib/tasks/route_translator.rake
|
45
64
|
- test/locales/routes.yml
|
@@ -65,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
84
|
version: '0'
|
66
85
|
requirements: []
|
67
86
|
rubyforge_project:
|
68
|
-
rubygems_version: 1.8.
|
87
|
+
rubygems_version: 1.8.23
|
69
88
|
signing_key:
|
70
89
|
specification_version: 3
|
71
90
|
summary: Translate your Rails routes in a simple manner
|