Skip to content
This repository
Browse code

I18n support for plugins

Rails will now automatically add locale files found in any engine's locale
directory to the I18n.load_path (i.e. files that match the glob pattern
"config/locales/**/*.{rb,yml}" relative to engine directories).

[#2325 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information...
commit cf4846c6ae991143afaef987a63c3ad9a3a2546b 1 parent 0efedf2
Antonio Tapiador authored March 24, 2009 jeremy committed August 30, 2009
2  railties/CHANGELOG
... ...
@@ -1,5 +1,7 @@
1 1
 *Edge*
2 2
 
  3
+* I18n support for plugins.  #2325 [Antonio Tapiador, Sven Fuchs]
  4
+
3 5
 * Ruby 1.9: use UTF-8 for default internal and external encodings.  [Jeremy Kemper]
4 6
 
5 7
 * Added db/seeds.rb as a default file for storing seed data for the database. Can be loaded with rake db:seed (or created alongside the db with db:setup). (This is also known as the "Stop Putting Gawd Damn Seed Data In Your Migrations" feature) [DHH]
12  railties/lib/rails/plugin.rb
@@ -71,6 +71,10 @@ def routed?
71 71
       File.exist?(routing_file)
72 72
     end
73 73
 
  74
+    # Returns true if there is any localization file in locale_path
  75
+    def localized?
  76
+      locale_files.any?
  77
+    end
74 78
 
75 79
     def view_path
76 80
       File.join(directory, 'app', 'views')
@@ -87,6 +91,14 @@ def metal_path
87 91
     def routing_file
88 92
       File.join(directory, 'config', 'routes.rb')
89 93
     end
  94
+
  95
+    def locale_path
  96
+      File.join(directory, 'config', 'locales')
  97
+    end
  98
+
  99
+    def locale_files
  100
+      Dir[ File.join(locale_path, '*.{rb,yml}') ]
  101
+    end
90 102
     
91 103
 
92 104
     private
7  railties/lib/rails/plugin/loader.rb
@@ -73,6 +73,7 @@ def engine_metal_paths
73 73
         def configure_engines
74 74
           if engines.any?
75 75
             add_engine_routing_configurations
  76
+            add_engine_locales
76 77
             add_engine_controller_paths
77 78
             add_engine_view_paths
78 79
           end
@@ -84,6 +85,12 @@ def add_engine_routing_configurations
84 85
           end
85 86
         end
86 87
 
  88
+        def add_engine_locales
  89
+          # reverse it such that the last engine can overwrite translations from the first, like with routes
  90
+          locale_files = engines.select(&:localized?).collect(&:locale_files).reverse.flatten
  91
+          I18n.load_path += locale_files - I18n.load_path
  92
+        end
  93
+
87 94
         def add_engine_controller_paths
88 95
           ActionController::Routing.controller_paths += engines.collect {|engine| engine.controller_path }
89 96
         end
2  railties/test/fixtures/plugins/engines/engine/config/locales/en.yml
... ...
@@ -0,0 +1,2 @@
  1
+en:
  2
+  hello: "Hello from Engine"
1  railties/test/initializer_test.rb
@@ -406,6 +406,7 @@ def test_config_defaults_and_settings_should_be_added_to_i18n_defaults
406 406
      File.expand_path(File.dirname(__FILE__) + "/../../actionpack/lib/action_view/locale/en.yml"),
407 407
      File.expand_path(File.dirname(__FILE__) + "/../../activemodel/lib/active_model/locale/en.yml"),
408 408
      File.expand_path(File.dirname(__FILE__) + "/../../activerecord/lib/active_record/locale/en.yml"),
  409
+     File.expand_path(File.dirname(__FILE__) + "/../../railties/test/fixtures/plugins/engines/engine/config/locales/en.yml"),
409 410
      "my/test/locale.yml",
410 411
      "my/other/locale.yml" ], I18n.load_path.collect { |path| path =~ /\.\./ ? File.expand_path(path) : path }
411 412
   end
8  railties/test/plugin_loader_test.rb
@@ -156,6 +156,14 @@ def test_should_add_all_load_paths_from_a_plugin_to_LOAD_PATH_array
156 156
     plugin_load_paths.each { |path| assert $LOAD_PATH.include?(path) }
157 157
   end
158 158
 
  159
+  def test_should_add_locale_files_to_I18n_load_path
  160
+    only_load_the_following_plugins! [:engine]
  161
+
  162
+    @loader.send :add_engine_locales
  163
+
  164
+    assert I18n.load_path.include?(File.join(plugin_fixture_path('engines/engine'), 'config', 'locales', 'en.yml'))
  165
+  end
  166
+
159 167
 
160 168
   private
161 169
     def reset_load_path!

1 note on commit cf4846c

Kieran Pilkington

Awesome. Now start on migrations/seed data.

Karel Minarik

Hi, this means only locale files directly in /config are loaded, and does not allow for nested locales like /my_plugin/app/config/locales/models/en.yml, /my_plugin/app/config/locales/defaults/en.yml, etc. Something like:

Dir[ File.join(locale_path, '**', '*.{rb,yml}') ]

would be better?

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