Skip to content

Commit

Permalink
Translate the routes automatically.
Browse files Browse the repository at this point in the history
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
jacob-carlborg committed Sep 19, 2012
1 parent 3605d2c commit 6cd300f
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 7 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Expand Up @@ -3,4 +3,6 @@ SampleApp/log/*.log
SampleApp/tmp/**/*
SampleApp/db/test.sqlite3
/.rvmrc
/Gemfile.lock
/Gemfile.lock
test/log
test/tmp
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -3,3 +3,4 @@ source "http://rubygems.org"
gemspec

gem "rails", "~> 3.2.6"
gem "rb-fsevent", :require => false if RUBY_PLATFORM =~ /darwin/i
8 changes: 8 additions & 0 deletions 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
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -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
------------

Expand Down
5 changes: 3 additions & 2 deletions lib/route_translator.rb
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
1 change: 1 addition & 0 deletions lib/route_translator/railtie.rb
Expand Up @@ -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|
Expand Down
13 changes: 12 additions & 1 deletion lib/route_translator/route_set.rb
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions 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
12 changes: 12 additions & 0 deletions 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
1 change: 1 addition & 0 deletions route_translator.gemspec
Expand Up @@ -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
51 changes: 50 additions & 1 deletion 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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
44 changes: 42 additions & 2 deletions test/test_helper.rb
@@ -1,3 +1,5 @@
require 'rails/application/route_inspector'

class StubbedI18nBackend
@@translations = {
'es' => { 'people' => 'gente'},
Expand All @@ -13,8 +15,6 @@ def self.translate(locale, key, options)
def self.available_locales
@@translations.keys
end


end

module RouteTranslator
Expand All @@ -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|
Expand Down

0 comments on commit 6cd300f

Please sign in to comment.