Skip to content
Browse files

Translate the routes automatically.

This change makes the call to "MyApp::Application.routes.translate_from_file"
unnecessary. It's still possible to call this function for backwards
compatibility.

It also adds a new config option, "translation_file", which can be used instead
of the call to "translate_from_file" to change the default translation file.
  • Loading branch information...
1 parent 3605d2c commit 6cd300f6a761a47bd316b519d80e57fa602906c1 @jacob-carlborg jacob-carlborg committed Sep 18, 2012
View
4 .gitignore
@@ -3,4 +3,6 @@ SampleApp/log/*.log
SampleApp/tmp/**/*
SampleApp/db/test.sqlite3
/.rvmrc
-/Gemfile.lock
+/Gemfile.lock
+test/log
+test/tmp
View
1 Gemfile
@@ -3,3 +3,4 @@ source "http://rubygems.org"
gemspec
gem "rails", "~> 3.2.6"
+gem "rb-fsevent", :require => false if RUBY_PLATFORM =~ /darwin/i
View
8 Guardfile
@@ -0,0 +1,8 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard :test do
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/route_translator_test.rb" }
+ watch(%r{^test/.+_test\.rb$})
+ watch('test/test_helper.rb') { "test" }
+end
View
3 README.md
@@ -148,6 +148,9 @@ end
* **force_locale** - Set this options to `true` to force the locale to be added
to all generated route paths, even for the default locale. Defaults to `false`
+* **translation_file** - Sets the translation file(s) used for translating the
+routes. Defaults to `config/i18n-routes.yml`
+
Contributing
------------
View
5 lib/route_translator.rb
@@ -4,6 +4,7 @@
require 'action_dispatch'
require 'route_translator/route_set'
+require 'route_translator/routes_reloader'
require 'route_translator/railtie' if defined?(Rails::Railtie)
module RouteTranslator
@@ -17,7 +18,7 @@ module RouteTranslator
ActionDispatch::Routing::UrlFor
].freeze
- Configuration = Struct.new(:force_locale)
+ Configuration = Struct.new(:force_locale, :translation_file)
def self.locale_suffix locale
locale.to_s.underscore
@@ -63,4 +64,4 @@ def locale_suffix locale
ActionController::Base.send(:include, RouteTranslator::Controller)
ActionDispatch::Routing::Mapper.send(:include, RouteTranslator::Mapper)
-ActionDispatch::Routing::RouteSet.send(:include, RouteTranslator::RouteSet)
+ActionDispatch::Routing::RouteSet.send(:include, RouteTranslator::RouteSet)
View
1 lib/route_translator/railtie.rb
@@ -5,6 +5,7 @@ class Railtie < ::Rails::Railtie
initializer "route_translator.set_configs" do |app|
options = app.config.route_translator
options.force_locale ||= false
+ options.translation_file ||= File.join(%w[config i18n-routes.yml])
ActiveSupport.on_load :route_translator do
options.each do |k, v|
View
13 lib/route_translator/route_set.rb
@@ -24,14 +24,25 @@ def translate_with_dictionary(&block)
#Use the translations from the specified file
def translate_from_file(file_path = nil)
- file_path ||= defined?(Rails) && File.join(Rails.root, %w(config i18n-routes.yml))
+ file_path = absolute_path(file_path)
+
reset_dictionary
Dir[file_path].each do |file|
add_dictionary_from_file(file)
end
translate
end
+private
+
+ def absolute_path (file_path)
+ file_path ||= RouteTranslator.config.translation_file
+ file_path = Rails.root.join(file_path) if defined?(Rails)
+ file_path
+ end
+
+public
+
include Helpers
include Translator
include DictionaryManagement
View
20 lib/route_translator/routes_reloader.rb
@@ -0,0 +1,20 @@
+require "rails"
+
+module Rails
+ class Application
+ class RoutesReloader
+ alias :__reload__! :reload!
+
+ def reload!
+ result = __reload__!
+
+ route_sets.each do |routes|
+ routes.default_locale = I18n.default_locale
+ routes.translate_from_file
+ end
+
+ result
+ end
+ end
+ end
+end
View
12 lib/route_translator/test_request.rb
@@ -0,0 +1,12 @@
+module ActionDispatch
+ class TestRequest < Request
+ def initialize(env = {})
+ env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
+ super(DEFAULT_ENV.merge(env))
+
+ self.host = 'test.host'
+ self.remote_addr = '0.0.0.0'
+ self.user_agent = 'Rails Testing'
+ end
+ end
+end
View
1 route_translator.gemspec
@@ -18,4 +18,5 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.add_runtime_dependency("mocha")
+ s.add_development_dependency("guard-test")
end
View
51 test/route_translator_test.rb
@@ -1,11 +1,14 @@
require 'test/unit'
require 'mocha'
+require "rails"
+require "action_controller/railtie"
+
require 'route_translator'
+require "route_translator/test_request"
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
-
class PeopleController < ActionController::Base; end
class ProductsController < ActionController::Base; end
@@ -21,14 +24,23 @@ def config_force_locale (force)
RouteTranslator.config.force_locale = force
end
+ def config_translation_file (file)
+ RouteTranslator.config.translation_file = file
+ end
+
def setup
+ setup_application
+
@controller = ActionController::Base.new
@view = ActionView::Base.new
@routes = ActionDispatch::Routing::RouteSet.new
end
def teardown
config_force_locale(false)
+ config_default_locale_settings("en")
+ app_file routes_config, ""
+ FileUtils.rm_rf "#{tmp_path}/log"
end
def test_unnamed_root_route
@@ -337,6 +349,43 @@ def test_force_locale
assert_unrecognized_route '/people', :controller => 'people', :action => 'index'
end
+ def test_config_translation_file
+ @routes.draw do
+ localized do
+ root :to => 'people#index'
+ end
+ end
+
+ config_default_locale_settings 'es'
+ config_translation_file File.expand_path('locales/routes.yml', File.dirname(__FILE__))
+
+ @routes.translate_from_file
+
+ assert_routing '/', :controller => 'people', :action => 'index', :locale => 'es'
+ assert_routing '/en', :controller => 'people', :action => 'index', :locale => 'en'
+ assert_unrecognized_route '/es', :controller => 'people', :action => 'index', :locale => 'es'
+ end
+
+ def test_auto_translate
+ app_file routes_config, <<-RUBY
+ Rails.application.routes.draw do
+ localized do
+ root :to => 'people#index'
+ end
+ end
+ RUBY
+
+ config_default_locale_settings 'es'
+ config_translation_file File.expand_path('locales/routes.yml', File.dirname(__FILE__))
+ app.reload_routes!
+
+ @routes = app.routes
+
+ assert_routing '/', :controller => 'people', :action => 'index', :locale => 'es'
+ assert_routing '/en', :controller => 'people', :action => 'index', :locale => 'en'
+ assert_unrecognized_route '/es', :controller => 'people', :action => 'index', :locale => 'es'
+ end
+
def test_action_controller_gets_locale_setter
ActionController::Base.instance_methods.include?('set_locale_from_url')
end
View
44 test/test_helper.rb
@@ -1,3 +1,5 @@
+require 'rails/application/route_inspector'
+
class StubbedI18nBackend
@@translations = {
'es' => { 'people' => 'gente'},
@@ -13,8 +15,6 @@ def self.translate(locale, key, options)
def self.available_locales
@@translations.keys
end
-
-
end
module RouteTranslator
@@ -32,6 +32,46 @@ def formatted_root_route?
!(defined?(ActionPack) && ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR > 0)
end
+ def setup_application
+ return if defined?(@@app)
+
+ app = Class.new(Rails::Application)
+ app.config.active_support.deprecation = :stderr
+ app.paths["log"] = "#{tmp_path}/log/test.log"
+ app.paths["config/routes"] = File.join(app_path, routes_config)
+ app.initialize!
+ @@app = Rails.application = app
+ end
+
+ def app
+ @@app
+ end
+
+ def tmp_path(*args)
+ @tmp_path ||= File.join(File.dirname(__FILE__), "tmp")
+ File.join(@tmp_path, *args)
+ end
+
+ def app_path(*args)
+ tmp_path(*%w[app] + args)
+ end
+
+ def app_file(path, contents)
+ FileUtils.mkdir_p File.dirname("#{app_path}/#{path}")
+ File.open("#{app_path}/#{path}", 'w') do |f|
+ f.puts contents
+ end
+ end
+
+ def routes_config
+ @@routes_config ||= File.join("config", "routes.rb")
+ end
+
+ def print_routes (route_set)
+ inspector = Rails::Application::RouteInspector.new
+ puts inspector.format(route_set.routes, ENV['CONTROLLER']).join "\n"
+ end
+
def assert_helpers_include(*helpers)
helpers.each do |helper|
['url', 'path'].each do |suffix|

0 comments on commit 6cd300f

Please sign in to comment.
Something went wrong with that request. Please try again.