Skip to content
This repository
Browse code

Added view path support for engines [DHH]

  • Loading branch information...
commit f2ee056873b84f8917e72d87181e1a9f5f653342 1 parent 229f959
David Heinemeier Hansson authored November 27, 2008
2  railties/CHANGELOG
... ...
@@ -1,5 +1,7 @@
1 1
 *2.3.0 [Edge]*
2 2
 
  3
+* Added view path support for engines [DHH]
  4
+
3 5
 * Added that config/routes.rb files in engine plugins are automatically loaded (and reloaded when they change in dev mode) [DHH]
4 6
 
5 7
 * Added app/[models|controllers|helpers] to the load path for plugins that has an app directory (go engines ;)) [DHH]
8  railties/lib/initializer.rb
@@ -487,12 +487,8 @@ def initialize_framework_views
487 487
     def initialize_routing
488 488
       return unless configuration.frameworks.include?(:action_controller)
489 489
 
490  
-      ActionController::Routing.controller_paths = configuration.controller_paths + plugin_loader.controller_paths
491  
-
492  
-      ([ configuration.routes_configuration_file ] + plugin_loader.routing_files).each do |routing_file|
493  
-        ActionController::Routing::Routes.add_configuration_file(routing_file)
494  
-      end
495  
-
  490
+      ActionController::Routing.controller_paths += configuration.controller_paths
  491
+      ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
496 492
       ActionController::Routing::Routes.reload
497 493
     end
498 494
 
11  railties/lib/rails/plugin.rb
@@ -71,6 +71,11 @@ def routed?
71 71
       File.exist?(routing_file)
72 72
     end
73 73
 
  74
+
  75
+    def view_path
  76
+      File.join(directory, 'app', 'views')
  77
+    end
  78
+
74 79
     def controller_path
75 80
       File.join(directory, 'app', 'controllers')
76 81
     end
@@ -95,11 +100,7 @@ def report_nonexistant_or_empty_plugin!
95 100
 
96 101
       
97 102
       def app_paths
98  
-        [ 
99  
-          File.join(directory, 'app', 'models'), 
100  
-          File.join(directory, 'app', 'controllers'),
101  
-          File.join(directory, 'app', 'helpers')
102  
-        ]
  103
+        [ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path ]
103 104
       end
104 105
       
105 106
       def lib_path
34  railties/lib/rails/plugin/loader.rb
@@ -39,6 +39,8 @@ def load_plugins
39 39
           register_plugin_as_loaded(plugin)
40 40
         end
41 41
 
  42
+        configure_engines
  43
+
42 44
         ensure_all_registered_plugins_are_loaded!
43 45
       end
44 46
       
@@ -63,19 +65,31 @@ def add_plugin_load_paths
63 65
         $LOAD_PATH.uniq!
64 66
       end
65 67
       
66  
-      # Returns an array of all the controller paths found inside engine-type plugins.
67  
-      def controller_paths
68  
-        engines.collect(&:controller_path)
69  
-      end
70  
-      
71  
-      # Returns an array of routing.rb files from all the plugins that include config/routes.rb
72  
-      def routing_files
73  
-        plugins.select(&:routed?).collect(&:routing_file)
74  
-      end
75  
-      
76 68
       
77 69
       protected
  70
+        def configure_engines
  71
+          if engines.any?
  72
+            add_engine_routing_configurations
  73
+            add_engine_controller_paths
  74
+            add_engine_view_paths
  75
+          end
  76
+        end
78 77
       
  78
+        def add_engine_routing_configurations
  79
+          engines.select(&:routed?).collect(&:routing_file).each do |routing_file|
  80
+            ActionController::Routing::Routes.add_configuration_file(routing_file)
  81
+          end
  82
+        end
  83
+        
  84
+        def add_engine_controller_paths
  85
+          ActionController::Routing.controller_paths += engines.collect(&:controller_path)
  86
+        end
  87
+        
  88
+        def add_engine_view_paths
  89
+          # reverse it such that the last engine can overwrite view paths from the first, like with routes
  90
+          ActionController::Base.view_paths += ActionView::PathSet.new(engines.collect(&:view_path).reverse)
  91
+        end
  92
+
79 93
         # The locate_plugins method uses each class in config.plugin_locators to
80 94
         # find the set of all plugins available to this Rails application.
81 95
         def locate_plugins
2  railties/test/fixtures/plugins/engines/engine/app/controllers/engine_controller.rb
... ...
@@ -1,2 +1,2 @@
1  
-class EngineController < ActionController::Base
  1
+class EngineController
2 2
 end
228  railties/test/plugin_loader_test.rb
... ...
@@ -1,5 +1,8 @@
1 1
 require 'plugin_test_helper'
2 2
 
  3
+$:.unshift File.dirname(__FILE__) + "/../../actionpack/lib"
  4
+require 'action_controller'
  5
+
3 6
 # Mocks out the configuration
4 7
 module Rails
5 8
   def self.configuration
@@ -7,149 +10,152 @@ def self.configuration
7 10
   end
8 11
 end
9 12
 
10  
-uses_mocha "Plugin Loader Tests" do
11  
-
12  
-  class TestPluginLoader < Test::Unit::TestCase
13  
-    ORIGINAL_LOAD_PATH = $LOAD_PATH.dup
14  
-
15  
-    def setup
16  
-      reset_load_path!
  13
+class TestPluginLoader < Test::Unit::TestCase
  14
+  ORIGINAL_LOAD_PATH = $LOAD_PATH.dup
17 15
 
18  
-      @configuration     = Rails::Configuration.new
19  
-      @configuration.plugin_paths << plugin_fixture_root_path
20  
-      @initializer       = Rails::Initializer.new(@configuration)
21  
-      @valid_plugin_path = plugin_fixture_path('default/stubby')
22  
-      @empty_plugin_path = plugin_fixture_path('default/empty')
  16
+  def setup
  17
+    reset_load_path!
23 18
 
24  
-      @failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
  19
+    @configuration     = Rails::Configuration.new
  20
+    @configuration.plugin_paths << plugin_fixture_root_path
  21
+    @initializer       = Rails::Initializer.new(@configuration)
  22
+    @valid_plugin_path = plugin_fixture_path('default/stubby')
  23
+    @empty_plugin_path = plugin_fixture_path('default/empty')
25 24
 
26  
-      @loader = Rails::Plugin::Loader.new(@initializer)
27  
-    end
  25
+    @failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
28 26
 
29  
-    def test_should_locate_plugins_by_asking_each_locator_specifed_in_configuration_for_its_plugins_result
30  
-      locator_1 = stub(:plugins => [:a, :b, :c])
31  
-      locator_2 = stub(:plugins => [:d, :e, :f])
32  
-      locator_class_1 = stub(:new => locator_1)
33  
-      locator_class_2 = stub(:new => locator_2)
34  
-      @configuration.plugin_locators = [locator_class_1, locator_class_2]
35  
-      assert_equal [:a, :b, :c, :d, :e, :f], @loader.send(:locate_plugins)
36  
-    end
  27
+    @loader = Rails::Plugin::Loader.new(@initializer)
  28
+  end
37 29
 
38  
-    def test_should_memoize_the_result_of_locate_plugins_as_all_plugins
39  
-      plugin_list = [:a, :b, :c]
40  
-      @loader.expects(:locate_plugins).once.returns(plugin_list)
41  
-      assert_equal plugin_list, @loader.all_plugins
42  
-      assert_equal plugin_list, @loader.all_plugins # ensuring that locate_plugins isn't called again
43  
-    end
  30
+  def test_should_locate_plugins_by_asking_each_locator_specifed_in_configuration_for_its_plugins_result
  31
+    locator_1 = stub(:plugins => [:a, :b, :c])
  32
+    locator_2 = stub(:plugins => [:d, :e, :f])
  33
+    locator_class_1 = stub(:new => locator_1)
  34
+    locator_class_2 = stub(:new => locator_2)
  35
+    @configuration.plugin_locators = [locator_class_1, locator_class_2]
  36
+    assert_equal [:a, :b, :c, :d, :e, :f], @loader.send(:locate_plugins)
  37
+  end
44 38
 
45  
-    def test_should_return_empty_array_if_configuration_plugins_is_empty
46  
-      @configuration.plugins = []
47  
-      assert_equal [], @loader.plugins
48  
-    end
  39
+  def test_should_memoize_the_result_of_locate_plugins_as_all_plugins
  40
+    plugin_list = [:a, :b, :c]
  41
+    @loader.expects(:locate_plugins).once.returns(plugin_list)
  42
+    assert_equal plugin_list, @loader.all_plugins
  43
+    assert_equal plugin_list, @loader.all_plugins # ensuring that locate_plugins isn't called again
  44
+  end
49 45
 
50  
-    def test_should_find_all_availble_plugins_and_return_as_all_plugins
51  
-      assert_plugins [ :engine, :stubby, :plugin_with_no_lib_dir, :gemlike, :acts_as_chunky_bacon, :a], @loader.all_plugins.reverse, @failure_tip
52  
-    end
  46
+  def test_should_return_empty_array_if_configuration_plugins_is_empty
  47
+    @configuration.plugins = []
  48
+    assert_equal [], @loader.plugins
  49
+  end
53 50
 
54  
-    def test_should_return_all_plugins_as_plugins_when_registered_plugin_list_is_untouched
55  
-      assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
56  
-    end
  51
+  def test_should_find_all_availble_plugins_and_return_as_all_plugins
  52
+    assert_plugins [ :engine, :stubby, :plugin_with_no_lib_dir, :gemlike, :acts_as_chunky_bacon, :a], @loader.all_plugins.reverse, @failure_tip
  53
+  end
57 54
 
58  
-    def test_should_return_all_plugins_as_plugins_when_registered_plugin_list_is_nil
59  
-      @configuration.plugins = nil
60  
-      assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
61  
-    end
  55
+  def test_should_return_all_plugins_as_plugins_when_registered_plugin_list_is_untouched
  56
+    assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
  57
+  end
62 58
 
63  
-    def test_should_return_specific_plugins_named_in_config_plugins_array_if_set
64  
-      plugin_names = [:acts_as_chunky_bacon, :stubby]
65  
-      only_load_the_following_plugins! plugin_names
66  
-      assert_plugins plugin_names, @loader.plugins
67  
-    end
  59
+  def test_should_return_all_plugins_as_plugins_when_registered_plugin_list_is_nil
  60
+    @configuration.plugins = nil
  61
+    assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
  62
+  end
68 63
 
69  
-    def test_should_respect_the_order_of_plugins_given_in_configuration
70  
-      plugin_names = [:stubby, :acts_as_chunky_bacon]
71  
-      only_load_the_following_plugins! plugin_names
72  
-      assert_plugins plugin_names, @loader.plugins
73  
-    end
  64
+  def test_should_return_specific_plugins_named_in_config_plugins_array_if_set
  65
+    plugin_names = [:acts_as_chunky_bacon, :stubby]
  66
+    only_load_the_following_plugins! plugin_names
  67
+    assert_plugins plugin_names, @loader.plugins
  68
+  end
74 69
 
75  
-    def test_should_load_all_plugins_in_natural_order_when_all_is_used
76  
-      only_load_the_following_plugins! [:all]
77  
-      assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
78  
-    end
  70
+  def test_should_respect_the_order_of_plugins_given_in_configuration
  71
+    plugin_names = [:stubby, :acts_as_chunky_bacon]
  72
+    only_load_the_following_plugins! plugin_names
  73
+    assert_plugins plugin_names, @loader.plugins
  74
+  end
79 75
 
80  
-    def test_should_load_specified_plugins_in_order_and_then_all_remaining_plugins_when_all_is_used
81  
-      only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon, :all]
82  
-      assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :engine, :gemlike, :plugin_with_no_lib_dir], @loader.plugins, @failure_tip
83  
-    end
  76
+  def test_should_load_all_plugins_in_natural_order_when_all_is_used
  77
+    only_load_the_following_plugins! [:all]
  78
+    assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
  79
+  end
84 80
 
85  
-    def test_should_be_able_to_specify_loading_of_plugins_loaded_after_all
86  
-      only_load_the_following_plugins!  [:stubby, :all, :acts_as_chunky_bacon]
87  
-      assert_plugins [:stubby, :a, :engine, :gemlike, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @loader.plugins, @failure_tip
88  
-    end
  81
+  def test_should_load_specified_plugins_in_order_and_then_all_remaining_plugins_when_all_is_used
  82
+    only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon, :all]
  83
+    assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :engine, :gemlike, :plugin_with_no_lib_dir], @loader.plugins, @failure_tip
  84
+  end
89 85
 
90  
-    def test_should_accept_plugin_names_given_as_strings
91  
-      only_load_the_following_plugins! ['stubby', 'acts_as_chunky_bacon', :a, :plugin_with_no_lib_dir]
92  
-      assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :plugin_with_no_lib_dir], @loader.plugins, @failure_tip
93  
-    end
  86
+  def test_should_be_able_to_specify_loading_of_plugins_loaded_after_all
  87
+    only_load_the_following_plugins!  [:stubby, :all, :acts_as_chunky_bacon]
  88
+    assert_plugins [:stubby, :a, :engine, :gemlike, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @loader.plugins, @failure_tip
  89
+  end
94 90
 
95  
-    def test_should_add_plugin_load_paths_to_global_LOAD_PATH_array
96  
-      only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
97  
-      stubbed_application_lib_index_in_LOAD_PATHS = 4
98  
-      @loader.stubs(:application_lib_index).returns(stubbed_application_lib_index_in_LOAD_PATHS)
  91
+  def test_should_accept_plugin_names_given_as_strings
  92
+    only_load_the_following_plugins! ['stubby', 'acts_as_chunky_bacon', :a, :plugin_with_no_lib_dir]
  93
+    assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :plugin_with_no_lib_dir], @loader.plugins, @failure_tip
  94
+  end
99 95
 
100  
-      @loader.add_plugin_load_paths
  96
+  def test_should_add_plugin_load_paths_to_global_LOAD_PATH_array
  97
+    only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
  98
+    stubbed_application_lib_index_in_LOAD_PATHS = 4
  99
+    @loader.stubs(:application_lib_index).returns(stubbed_application_lib_index_in_LOAD_PATHS)
101 100
 
102  
-      assert $LOAD_PATH.index(File.join(plugin_fixture_path('default/stubby'), 'lib')) >= stubbed_application_lib_index_in_LOAD_PATHS
103  
-      assert $LOAD_PATH.index(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib')) >= stubbed_application_lib_index_in_LOAD_PATHS
104  
-    end
  101
+    @loader.add_plugin_load_paths
105 102
 
106  
-    def test_should_add_plugin_load_paths_to_Dependencies_load_paths
107  
-      only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
  103
+    assert $LOAD_PATH.index(File.join(plugin_fixture_path('default/stubby'), 'lib')) >= stubbed_application_lib_index_in_LOAD_PATHS
  104
+    assert $LOAD_PATH.index(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib')) >= stubbed_application_lib_index_in_LOAD_PATHS
  105
+  end
108 106
 
109  
-      @loader.add_plugin_load_paths
  107
+  def test_should_add_plugin_load_paths_to_Dependencies_load_paths
  108
+    only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
110 109
 
111  
-      assert ActiveSupport::Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
112  
-      assert ActiveSupport::Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
113  
-    end
  110
+    @loader.add_plugin_load_paths
114 111
 
  112
+    assert ActiveSupport::Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
  113
+    assert ActiveSupport::Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
  114
+  end
115 115
 
116  
-    def test_should_add_engine_load_paths_to_Dependencies_load_paths
117  
-      only_load_the_following_plugins! [:engine]
  116
+  def test_should_add_engine_load_paths_to_Dependencies_load_paths
  117
+    only_load_the_following_plugins! [:engine]
118 118
 
119  
-      @loader.add_plugin_load_paths
  119
+    @loader.add_plugin_load_paths
120 120
 
121  
-      %w( models controllers helpers ).each do |app_part|
122  
-        assert ActiveSupport::Dependencies.load_paths.include?(
123  
-          File.join(plugin_fixture_path('engines/engine'), 'app', app_part)
124  
-        ), "Couldn't find #{app_part} in load path"
125  
-      end
  121
+    %w( models controllers helpers ).each do |app_part|
  122
+      assert ActiveSupport::Dependencies.load_paths.include?(
  123
+        File.join(plugin_fixture_path('engines/engine'), 'app', app_part)
  124
+      ), "Couldn't find #{app_part} in load path"
126 125
     end
  126
+  end
  127
+  
  128
+  def test_engine_controllers_should_have_their_view_path_set_when_loaded
  129
+    only_load_the_following_plugins!([ :engine ])
127 130
 
128  
-    def test_should_add_plugin_load_paths_to_Dependencies_load_once_paths
129  
-      only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
130  
-
131  
-      @loader.add_plugin_load_paths
  131
+    @loader.send :add_engine_view_paths
  132
+    
  133
+    assert_equal [ File.join(plugin_fixture_path('engines/engine'), 'app', 'views') ], ActionController::Base.view_paths
  134
+  end
132 135
 
133  
-      assert ActiveSupport::Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
134  
-      assert ActiveSupport::Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
135  
-    end
  136
+  def test_should_add_plugin_load_paths_to_Dependencies_load_once_paths
  137
+    only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
136 138
 
137  
-    def test_should_add_all_load_paths_from_a_plugin_to_LOAD_PATH_array
138  
-      plugin_load_paths = ["a", "b"]
139  
-      plugin = stub(:load_paths => plugin_load_paths)
140  
-      @loader.stubs(:plugins).returns([plugin])
  139
+    @loader.add_plugin_load_paths
141 140
 
142  
-      @loader.add_plugin_load_paths
  141
+    assert ActiveSupport::Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
  142
+    assert ActiveSupport::Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
  143
+  end
143 144
 
144  
-      plugin_load_paths.each { |path| assert $LOAD_PATH.include?(path) }
145  
-    end
  145
+  def test_should_add_all_load_paths_from_a_plugin_to_LOAD_PATH_array
  146
+    plugin_load_paths = ["a", "b"]
  147
+    plugin = stub(:load_paths => plugin_load_paths)
  148
+    @loader.stubs(:plugins).returns([plugin])
146 149
 
147  
-    private
  150
+    @loader.add_plugin_load_paths
148 151
 
149  
-      def reset_load_path!
150  
-        $LOAD_PATH.clear
151  
-        ORIGINAL_LOAD_PATH.each { |path| $LOAD_PATH << path }
152  
-      end
  152
+    plugin_load_paths.each { |path| assert $LOAD_PATH.include?(path) }
153 153
   end
154 154
 
155  
-end
  155
+
  156
+  private
  157
+    def reset_load_path!
  158
+      $LOAD_PATH.clear
  159
+      ORIGINAL_LOAD_PATH.each { |path| $LOAD_PATH << path }
  160
+    end
  161
+end

0 notes on commit f2ee056

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