rails-translate-routes 0.0.1

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/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "rails", ">= 3.0"
4
+
5
+ # Add dependencies to develop your gem here.
6
+ # Include everything needed to run rake, tests, features, etc.
7
+ group :development do
8
+ gem "bundler", "~> 1.0.0"
9
+ gem "jeweler", "~> 1.6.4"
10
+ gem 'sqlite3'
11
+ gem "minitest"
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,98 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ actionmailer (3.1.3)
5
+ actionpack (= 3.1.3)
6
+ mail (~> 2.3.0)
7
+ actionpack (3.1.3)
8
+ activemodel (= 3.1.3)
9
+ activesupport (= 3.1.3)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ i18n (~> 0.6)
13
+ rack (~> 1.3.5)
14
+ rack-cache (~> 1.1)
15
+ rack-mount (~> 0.8.2)
16
+ rack-test (~> 0.6.1)
17
+ sprockets (~> 2.0.3)
18
+ activemodel (3.1.3)
19
+ activesupport (= 3.1.3)
20
+ builder (~> 3.0.0)
21
+ i18n (~> 0.6)
22
+ activerecord (3.1.3)
23
+ activemodel (= 3.1.3)
24
+ activesupport (= 3.1.3)
25
+ arel (~> 2.2.1)
26
+ tzinfo (~> 0.3.29)
27
+ activeresource (3.1.3)
28
+ activemodel (= 3.1.3)
29
+ activesupport (= 3.1.3)
30
+ activesupport (3.1.3)
31
+ multi_json (~> 1.0)
32
+ arel (2.2.1)
33
+ builder (3.0.0)
34
+ erubis (2.7.0)
35
+ git (1.2.5)
36
+ hike (1.2.1)
37
+ i18n (0.6.0)
38
+ jeweler (1.6.4)
39
+ bundler (~> 1.0)
40
+ git (>= 1.2.5)
41
+ rake
42
+ json (1.6.4)
43
+ mail (2.3.0)
44
+ i18n (>= 0.4.0)
45
+ mime-types (~> 1.16)
46
+ treetop (~> 1.4.8)
47
+ mime-types (1.17.2)
48
+ minitest (2.10.0)
49
+ multi_json (1.0.4)
50
+ polyglot (0.3.3)
51
+ rack (1.3.6)
52
+ rack-cache (1.1)
53
+ rack (>= 0.4)
54
+ rack-mount (0.8.3)
55
+ rack (>= 1.0.0)
56
+ rack-ssl (1.3.2)
57
+ rack
58
+ rack-test (0.6.1)
59
+ rack (>= 1.0)
60
+ rails (3.1.3)
61
+ actionmailer (= 3.1.3)
62
+ actionpack (= 3.1.3)
63
+ activerecord (= 3.1.3)
64
+ activeresource (= 3.1.3)
65
+ activesupport (= 3.1.3)
66
+ bundler (~> 1.0)
67
+ railties (= 3.1.3)
68
+ railties (3.1.3)
69
+ actionpack (= 3.1.3)
70
+ activesupport (= 3.1.3)
71
+ rack-ssl (~> 1.3.2)
72
+ rake (>= 0.8.7)
73
+ rdoc (~> 3.4)
74
+ thor (~> 0.14.6)
75
+ rake (0.9.2.2)
76
+ rdoc (3.12)
77
+ json (~> 1.4)
78
+ sprockets (2.0.3)
79
+ hike (~> 1.2)
80
+ rack (~> 1.0)
81
+ tilt (~> 1.1, != 1.3.0)
82
+ sqlite3 (1.3.5)
83
+ thor (0.14.6)
84
+ tilt (1.3.3)
85
+ treetop (1.4.10)
86
+ polyglot
87
+ polyglot (>= 0.3.1)
88
+ tzinfo (0.3.31)
89
+
90
+ PLATFORMS
91
+ ruby
92
+
93
+ DEPENDENCIES
94
+ bundler (~> 1.0.0)
95
+ jeweler (~> 1.6.4)
96
+ minitest
97
+ rails (>= 3.0)
98
+ sqlite3
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Francesc Pla
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,163 @@
1
+ = rails-translate-routes
2
+
3
+ Rails 3.x routes translations based on Raul's translate_routes (https://github.com/raul/translate_routes).
4
+
5
+ It's currently a stripped down version of the forked gem, adding some bugfixes for rails 3.1 and features I needed for my project. See doc below to see what it can do.
6
+
7
+ translate_routes & i18n_routes seems to be unmaintained projects so I decided to start a fork of the first one for my own projects, I can't promise high dedication but I'll to maintain it for my own use and take care all patches & bugs submitted, help is welcome!
8
+
9
+ == Installation
10
+
11
+ Add it to your Gemfile:
12
+
13
+ gem 'rails-translate-routes'
14
+
15
+ == Basic usage
16
+
17
+ Let's imagine you have a SampleApp with products and a contact page. A typical 'routes.rb' file should look like:
18
+
19
+ SampleApp::Application.routes.draw do
20
+ resources :products
21
+ match 'contact', :to => 'pages#contact'
22
+ end
23
+
24
+ Running 'rake routes' we have:
25
+
26
+ products GET /products(.:format) {:action=>"index", :controller=>"products"}
27
+ POST /products(.:format) {:action=>"create", :controller=>"products"}
28
+ new_product GET /products/new(.:format) {:action=>"new", :controller=>"products"}
29
+ edit_product GET /products/:id/edit(.:format) {:action=>"edit", :controller=>"products"}
30
+ product GET /products/:id(.:format) {:action=>"show", :controller=>"products"}
31
+ PUT /products/:id(.:format) {:action=>"update", :controller=>"products"}
32
+ DELETE /products/:id(.:format) {:action=>"destroy", :controller=>"products"}
33
+ contact /contact(.:format) {:action=>"contact", :controller=>"pages"}
34
+
35
+ We want to have them in two languages english and spanish, to accomplish this with rails-translate-routes:
36
+
37
+ 1) We have to activate the translations appending this line to the end of 'routes.rb'
38
+
39
+ ActionDispatch::Routing::Translator.translate_from_file('config/locales/routes.yml')
40
+
41
+ 2) Now we can write translations on a standard YAML file (e.g: in config/locales/routes.yml), including all the locales and their translations:
42
+
43
+ en:
44
+ # you can leave empty locales, for example the default one
45
+ es:
46
+ products: productos
47
+ contact: contacto
48
+ new: crear
49
+
50
+ 3) Include this filter in your ApplicationController:
51
+
52
+ before_filter :set_locale_from_url
53
+
54
+ Also remember to include language detection to your app, a simple example of an ApplicationController
55
+
56
+ class ApplicationController < ActionController::Base
57
+ protect_from_forgery
58
+
59
+ before_filter :set_locale
60
+ before_filter :set_locale_from_url
61
+
62
+ private
63
+
64
+ def set_locale
65
+ I18n.locale = params[:locale] || ((lang = request.env['HTTP_ACCEPT_LANGUAGE']) && lang[/^[a-z]{2}/])
66
+ end
67
+ end
68
+
69
+ And that's it! Now if we execute 'rake routes':
70
+
71
+ products_en GET /products(.:format) {:action=>"index", :controller=>"products"}
72
+ products_es GET /es/productos(.:format) {:action=>"index", :controller=>"products"}
73
+ POST /products(.:format) {:action=>"create", :controller=>"products"}
74
+ POST /es/productos(.:format) {:action=>"create", :controller=>"products"}
75
+ new_product_en GET /products/new(.:format) {:action=>"new", :controller=>"products"}
76
+ new_product_es GET /es/productos/new(.:format) {:action=>"new", :controller=>"products"}
77
+ edit_product_en GET /products/:id/edit(.:format) {:action=>"edit", :controller=>"products"}
78
+ edit_product_es GET /es/productos/:id/edit(.:format) {:action=>"edit", :controller=>"products"}
79
+ product_en GET /products/:id(.:format) {:action=>"show", :controller=>"products"}
80
+ product_es GET /es/productos/:id(.:format) {:action=>"show", :controller=>"products"}
81
+ PUT /products/:id(.:format) {:action=>"update", :controller=>"products"}
82
+ PUT /es/productos/:id(.:format) {:action=>"update", :controller=>"products"}
83
+ DELETE /products/:id(.:format) {:action=>"destroy", :controller=>"products"}
84
+ DELETE /es/productos/:id(.:format) {:action=>"destroy", :controller=>"products"}
85
+ contact_en /contact(.:format) {:action=>"contact", :controller=>"pages"}
86
+ contact_es /es/contacto(.:format) {:action=>"contact", :controller=>"pages"}
87
+
88
+
89
+ The application recognizes the different routes and sets the 'I18n.locale' value in controllers, but what about the routes generation? As you can see on the previous rake routes execution, the 'contact_es_path' and 'contact_en_path' routing helpers have been generated and are available in your controllers and views. Additionally, a 'contact_path' helper has been generated, which generates the routes according to the current request's locale. This means that if you use named routes you don't need to modify your application links because the routing helpers are automatically adapted to the current locale.
90
+
91
+ <b>URL structure options</b>
92
+
93
+ As you can see by default it generates the following url structure:
94
+
95
+ /
96
+ /es
97
+ /products/
98
+ /es/productos/
99
+ /contact/
100
+ /es/contactos/
101
+
102
+ In case you want the default languages to be scoped resulting in the following structure:
103
+
104
+ /en
105
+ /es
106
+ /en/products/
107
+ /es/productos/
108
+ /en/contact/
109
+ /es/contactos/
110
+
111
+ You can specify the following option:
112
+
113
+ ActionDispatch::Routing::Translator.translate_from_file('config/locales/routes.yml', { :prefix_on_default_locale => true })
114
+
115
+ If you use the 'prefix_on_default_locale' you will have to make the proper redirect on your root controller from http://www.sampleapp.com/ to http://www.sampleapp.com/en or http://www.sampleapp.com/es rails-translate-routes adds an extra unstranslated root path:
116
+
117
+ root_en /en {:controller=>"pages", :action=>"index"}
118
+ root_es /es {:controller=>"pages", :action=>"index"}
119
+ root / {:controller=>"pages", :action=>"index"}
120
+
121
+ A simple example of a redirection to user locale in index method:
122
+
123
+ def index
124
+ unless params[ :locale]
125
+ # it takes I18n.locale from the previous example set_locale as before_filter in application controller
126
+ redirect_to eval("root_#{I18n.locale}_path
127
+ end
128
+
129
+ # rest of the controller logic ...
130
+ end
131
+
132
+ == TODO
133
+
134
+ Help is welcome ;)
135
+
136
+ * make basic testing
137
+ * support for rails 3.2
138
+
139
+ == Credits
140
+
141
+ Thanks to:
142
+
143
+ * Main development of forked gem:
144
+ * Raul Murciano (http://github.com/raul)
145
+
146
+ * Contributors of forked gem:
147
+ * Aitor Garay-Romero (http://github.com/aitorgr)
148
+ * Christian Hølmer (http://github.com/hoelmer)
149
+ * Nico Ritsche (https://github.com/ncri)
150
+ * Cedric Darricau (http://github.com/devsigner)
151
+ * Olivier Gonzalez (http://github.com/gonzoyumo)
152
+ * Kristian Mandrup (http://github.com/kristianmandrup)
153
+ * Pieter Visser (http://github.com/pietervisser)
154
+ * Marian Theisen (http://github.com/cice)
155
+ * Enric Lluelles (http://github.com/enriclluelles)
156
+ * Jaime Iniesta (http://github.com/jaimeiniesta)
157
+
158
+ == Similar projects
159
+
160
+ There are other two projects for translating routes in Rails (which I know of), both of them are unfortunately unmaintained but you may want to check them out if you use Rails 2 or have different needs.
161
+
162
+ * translate_routes (https://github.com/raul/translate_routes)
163
+ * i18n_routing (https://github.com/kwi/i18n_routing)
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "rails-translate-routes"
18
+ gem.homepage = "http://github.com/francesc/rails-translate-routes"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Simple gem to translate routes in Rails 3.x}
21
+ gem.description = %Q{Simple gem to translate routes in Rails 3.x based on translate_routes}
22
+ gem.email = "francesc@francesc.net"
23
+ gem.authors = ["Francesc Pla"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "rails-translate-routes #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,332 @@
1
+ # coding: UTF-8
2
+
3
+ # This class knows nothing
4
+ # about Rails.root or Rails.application.routes, and therefor is easier to
5
+ # test without an Rails App.
6
+ class RailsTranslateRoutes
7
+ TRANSLATABLE_SEGMENT = /^(\w+)(\()?/.freeze
8
+ LOCALE_PARAM_KEY = :locale.freeze
9
+ ROUTE_HELPER_CONTAINER = [
10
+ ActionController::Base,
11
+ ActionView::Base,
12
+ ActionMailer::Base,
13
+ ActionDispatch::Routing::UrlFor
14
+ ].freeze
15
+
16
+ # Attributes
17
+
18
+ attr_accessor :dictionary
19
+
20
+ def available_locales
21
+ @available_locales ||= I18n.available_locales.map(&:to_s)
22
+ end
23
+
24
+ def available_locales= locales
25
+ @available_locales = locales.map(&:to_s)
26
+ end
27
+
28
+ def default_locale
29
+ @default_locale ||= I18n.default_locale.to_s
30
+ end
31
+
32
+ def default_locale= locale
33
+ @default_locale = locale.to_s
34
+ end
35
+
36
+ def default_locale? locale
37
+ default_locale == locale.to_s
38
+ end
39
+
40
+ def prefix_on_default_locale
41
+ @prefix_on_default_locale ||= I18n.default_locale.to_s
42
+ end
43
+
44
+ def prefix_on_default_locale= locale
45
+ @prefix_on_default_locale = locale.to_s
46
+ end
47
+
48
+ class << self
49
+ # Default locale suffix generator
50
+ def locale_suffix locale
51
+ locale.to_s.underscore
52
+ end
53
+
54
+ # Creates a RailsTranslateRoutes instance, using I18n dictionaries of
55
+ # your app
56
+ def init_with_i18n *wanted_locales
57
+ new.tap do |t|
58
+ t.init_i18n_dictionary *wanted_locales
59
+ end
60
+ end
61
+
62
+ # Creates a RailsTranslateRoutes instance and evaluates given block
63
+ # with an empty dictionary
64
+ def init_with_yield &block
65
+ new.tap do |t|
66
+ t.yield_dictionary &block
67
+ end
68
+ end
69
+
70
+ # Creates a RailsTranslateRoutes instance and reads the translations
71
+ # from a specified file
72
+ def init_from_file file_path
73
+ new.tap do |t|
74
+ t.load_dictionary_from_file file_path
75
+ end
76
+ end
77
+ end
78
+
79
+ module DictionaryManagement
80
+ # Resets dictionary and yields the block wich can be used to manually fill the dictionary
81
+ # with translations e.g.
82
+ # route_translator = RailsTranslateRoutes.new
83
+ # route_translator.yield_dictionary do |dict|
84
+ # dict['en'] = { 'people' => 'people' }
85
+ # dict['de'] = { 'people' => 'personen' }
86
+ # end
87
+ def yield_dictionary &block
88
+ reset_dictionary
89
+ yield @dictionary
90
+ set_available_locales_from_dictionary
91
+ end
92
+
93
+ # Resets dictionary and loads translations from specified file
94
+ # config/locales/routes.yml:
95
+ # en:
96
+ # people: people
97
+ # de:
98
+ # people: personen
99
+ # routes.rb:
100
+ # ... your routes ...
101
+ # ActionDispatch::Routing::Translator.translate_from_file
102
+ # or, to specify a custom file
103
+ # ActionDispatch::Routing::Translator.translate_from_file 'config', 'locales', 'routes.yml'
104
+ def load_dictionary_from_file file_path
105
+ reset_dictionary
106
+ add_dictionary_from_file file_path
107
+ end
108
+
109
+ # Add translations from another file to the dictionary.
110
+ def add_dictionary_from_file file_path
111
+ yaml = YAML.load_file(file_path)
112
+ yaml.each_pair do |locale, translations|
113
+ merge_translations locale, translations
114
+ end
115
+ set_available_locales_from_dictionary
116
+ end
117
+
118
+ # Merge translations for a specified locale into the dictionary
119
+ def merge_translations locale, translations
120
+ locale = locale.to_s
121
+ if translations.blank?
122
+ @dictionary[locale] ||= {}
123
+ return
124
+ end
125
+ @dictionary[locale] = (@dictionary[locale] || {}).merge(translations)
126
+ end
127
+
128
+ # Init dictionary to use I18n to translate route parts. Creates
129
+ # a hash with a block for each locale to lookup keys in I18n dynamically.
130
+ def init_i18n_dictionary *wanted_locales
131
+ wanted_locales = available_locales if wanted_locales.blank?
132
+ reset_dictionary
133
+ wanted_locales.each do |locale|
134
+ @dictionary[locale] = Hash.new do |hsh, key|
135
+ hsh[key] = I18n.translate key, :locale => locale #DISCUSS: caching or no caching (store key and translation in dictionary?)
136
+ end
137
+ end
138
+ @available_locales = @dictionary.keys.map &:to_s
139
+ end
140
+
141
+ private
142
+ def set_available_locales_from_dictionary
143
+ @available_locales = @dictionary.keys.map &:to_s
144
+ end
145
+
146
+ # Resets dictionary
147
+ def reset_dictionary
148
+ @dictionary = { default_locale => {}}
149
+ end
150
+ end
151
+ include DictionaryManagement
152
+
153
+ module Translator
154
+ # Translate a specific RouteSet, usually Rails.application.routes, but can
155
+ # be a RouteSet of a gem, plugin/engine etc.
156
+ def translate route_set
157
+ Rails.logger.info "Translating routes (default locale: #{default_locale})" if defined?(Rails) && defined?(Rails.logger)
158
+
159
+ # save original routes and clear route set
160
+ original_routes = route_set.routes.dup # Array [routeA, routeB, ...]
161
+ original_routes.delete_if{|r| r.path == '/assets'}
162
+ original_named_routes = route_set.named_routes.routes.dup # Hash {:name => :route}
163
+
164
+ reset_route_set route_set
165
+
166
+ original_routes.each do |original_route|
167
+ translations_for(original_route).each do |translated_route_args|
168
+ route_set.add_route *translated_route_args
169
+ end
170
+ end
171
+
172
+ original_named_routes.each_key do |route_name|
173
+ route_set.named_routes.helpers.concat add_untranslated_helpers_to_controllers_and_views(route_name)
174
+ end
175
+
176
+ if root_route = original_named_routes[:root]
177
+ add_root_route root_route, route_set
178
+ end
179
+
180
+ end
181
+
182
+ # Add unmodified root route to route_set
183
+ def add_root_route root_route, route_set
184
+ if @prefix_on_default_locale
185
+ root_route.conditions[:path_info] = root_route.conditions[:path_info].dup
186
+ route_set.set.add_route *root_route
187
+ route_set.named_routes[root_route.name] = root_route
188
+ route_set.routes << root_route
189
+ end
190
+ end
191
+
192
+ # Add standard route helpers for default locale e.g.
193
+ # I18n.locale = :de
194
+ # people_path -> people_de_path
195
+ # I18n.locale = :fr
196
+ # people_path -> people_fr_path
197
+ def add_untranslated_helpers_to_controllers_and_views old_name
198
+ ['path', 'url'].map do |suffix|
199
+ new_helper_name = "#{old_name}_#{suffix}"
200
+
201
+ ROUTE_HELPER_CONTAINER.each do |helper_container|
202
+ helper_container.send :define_method, new_helper_name do |*args|
203
+ send "#{old_name}_#{locale_suffix(I18n.locale)}_#{suffix}", *args
204
+ end
205
+ end
206
+
207
+ new_helper_name.to_sym
208
+ end
209
+ end
210
+
211
+ # Generate translations for a single route for all available locales
212
+ def translations_for route
213
+ available_locales.map do |locale|
214
+ translate_route route, locale
215
+ end
216
+ end
217
+
218
+ # Generate translation for a single route for one locale
219
+ def translate_route route, locale
220
+ conditions = { :path_info => translate_path(route.path, locale) }
221
+ conditions[:request_method] = parse_request_methods route.conditions[:request_method] if route.conditions.has_key? :request_method
222
+ requirements = route.requirements.merge LOCALE_PARAM_KEY => locale
223
+ defaults = route.defaults.merge LOCALE_PARAM_KEY => locale
224
+ new_name = "#{route.name}_#{locale_suffix(locale)}" if route.name
225
+
226
+ [route.app, conditions, requirements, defaults, new_name]
227
+ end
228
+
229
+ # Add prefix for all non-default locales
230
+ def add_prefix? locale
231
+ if !default_locale?(locale) || @prefix_on_default_locale
232
+ true
233
+ else
234
+ false
235
+ end
236
+ end
237
+
238
+ # Translates a path and adds the locale prefix.
239
+ def translate_path path, locale
240
+ final_optional_segments = path.match(/(\(.+\))$/)[1] rescue nil # i.e: (.:format)
241
+ path_without_optional_segments = final_optional_segments ? path.gsub(final_optional_segments,'') : path
242
+ path_segments = path_without_optional_segments.split("/")
243
+ new_path = path_segments.map{ |seg| translate_path_segment(seg, locale) }.join('/')
244
+ new_path = "/#{locale.downcase}#{new_path}" if add_prefix?(locale)
245
+ new_path = '/' if new_path.blank?
246
+ final_optional_segments ? new_path + final_optional_segments : new_path
247
+ end
248
+
249
+ # Tries to translate a single path segment. If the path segment
250
+ # contains sth. like a optional format "people(.:format)", only
251
+ # "people" will be translated, if there is no translation, the path
252
+ # segment is blank or begins with a ":" (param key), the segment
253
+ # is returned untouched
254
+ def translate_path_segment segment, locale
255
+ return segment if segment.blank? or segment.starts_with?(":")
256
+
257
+ match = TRANSLATABLE_SEGMENT.match(segment)[1] rescue nil
258
+
259
+ (translate_string(match, locale) || segment).downcase
260
+ end
261
+
262
+ def translate_string str, locale
263
+ @dictionary[locale.to_s][str.to_s]
264
+ end
265
+
266
+ private
267
+ def reset_route_set route_set
268
+ route_set.clear!
269
+ remove_all_methods_in route_set.named_routes.module
270
+ end
271
+
272
+ def remove_all_methods_in mod
273
+ mod.instance_methods.each do |method|
274
+ mod.send :remove_method, method
275
+ end
276
+ end
277
+
278
+ # expects methods regexp to be in a format: /^GET$/ or /^GET|POST$/ and returns array ["GET", "POST"]
279
+ def parse_request_methods methods_regexp
280
+ methods_regexp.source.gsub(/\^([a-zA-Z\|]+)\$/, "\\1").split("|")
281
+ end
282
+ end
283
+ include Translator
284
+
285
+ def locale_suffix locale
286
+ self.class.locale_suffix locale
287
+ end
288
+ end
289
+
290
+ # Adapter for Rails 3 Apps
291
+ module ActionDispatch
292
+ module Routing
293
+ module Translator
294
+ class << self
295
+ def translate &block
296
+ RailsTranslateRoutes.init_with_yield(&block).translate Rails.application.routes
297
+ end
298
+
299
+ def translate_from_file(file_path, options = {})
300
+ file_path = %w(config locales routes.yml) if file_path.blank?
301
+ r = RailsTranslateRoutes.init_from_file(File.join(Rails.root, file_path))
302
+ r.prefix_on_default_locale = true if options && options[:prefix_on_default_locale] == true
303
+ r.translate Rails.application.routes
304
+ end
305
+
306
+ def i18n *locales
307
+ RailsTranslateRoutes.init_with_i18n(*locales).translate Rails.application.routes
308
+ end
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ # Add set_locale_from_url to controllers
315
+ ActionController::Base.class_eval do
316
+ private
317
+ # called by before_filter
318
+ def set_locale_from_url
319
+ I18n.locale = params[RailsTranslateRoutes::LOCALE_PARAM_KEY]
320
+ default_url_options = {RailsTranslateRoutes::LOCALE_PARAM_KEY => I18n.locale}
321
+ end
322
+ end
323
+
324
+ # Add locale_suffix to controllers, views and mailers
325
+ RailsTranslateRoutes::ROUTE_HELPER_CONTAINER.each do |klass|
326
+ klass.class_eval do
327
+ private
328
+ def locale_suffix locale
329
+ RailsTranslateRoutes.locale_suffix locale
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "rails-translate-routes"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Francesc Pla"]
12
+ s.date = "2012-01-04"
13
+ s.description = "Simple gem to translate routes in Rails 3.x based on translate_routes"
14
+ s.email = "francesc@francesc.net"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/rails-translate-routes.rb",
28
+ "rails-translate-routes.gemspec",
29
+ "test/helper.rb",
30
+ "test/test_rails-translate-routes.rb"
31
+ ]
32
+ s.homepage = "http://github.com/francesc/rails-translate-routes"
33
+ s.licenses = ["MIT"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = "1.8.10"
36
+ s.summary = "Simple gem to translate routes in Rails 3.x"
37
+
38
+ if s.respond_to? :specification_version then
39
+ s.specification_version = 3
40
+
41
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
42
+ s.add_runtime_dependency(%q<rails>, [">= 3.0"])
43
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
44
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
45
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
46
+ s.add_development_dependency(%q<minitest>, [">= 0"])
47
+ else
48
+ s.add_dependency(%q<rails>, [">= 3.0"])
49
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
50
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
51
+ s.add_dependency(%q<sqlite3>, [">= 0"])
52
+ s.add_dependency(%q<minitest>, [">= 0"])
53
+ end
54
+ else
55
+ s.add_dependency(%q<rails>, [">= 3.0"])
56
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
58
+ s.add_dependency(%q<sqlite3>, [">= 0"])
59
+ s.add_dependency(%q<minitest>, [">= 0"])
60
+ end
61
+ end
62
+
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ # coding: UTF-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+
13
+ require 'minitest/autorun'
14
+ require 'active_record'
15
+
16
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
17
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
18
+ require 'rails-translate-routes'
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestRailsTranslateRoutes < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-translate-routes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Francesc Pla
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70118983572120 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70118983572120
25
+ - !ruby/object:Gem::Dependency
26
+ name: bundler
27
+ requirement: &70118983571560 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70118983571560
36
+ - !ruby/object:Gem::Dependency
37
+ name: jeweler
38
+ requirement: &70118983570720 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.6.4
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70118983570720
47
+ - !ruby/object:Gem::Dependency
48
+ name: sqlite3
49
+ requirement: &70118983570020 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70118983570020
58
+ - !ruby/object:Gem::Dependency
59
+ name: minitest
60
+ requirement: &70118983592020 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70118983592020
69
+ description: Simple gem to translate routes in Rails 3.x based on translate_routes
70
+ email: francesc@francesc.net
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - LICENSE.txt
75
+ - README.rdoc
76
+ files:
77
+ - .document
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE.txt
81
+ - README.rdoc
82
+ - Rakefile
83
+ - VERSION
84
+ - lib/rails-translate-routes.rb
85
+ - rails-translate-routes.gemspec
86
+ - test/helper.rb
87
+ - test/test_rails-translate-routes.rb
88
+ homepage: http://github.com/francesc/rails-translate-routes
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ segments:
102
+ - 0
103
+ hash: -1794154583192669933
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.8.10
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Simple gem to translate routes in Rails 3.x
116
+ test_files: []