Skip to content
This repository
Browse code

Added ability to set asset_path for engines

  • Loading branch information...
commit a132229d7b4382d9ffe8847fa58f469cb8f2ecfc 1 parent abeb0ff
Piotr Sarnacki authored
2  actionpack/lib/action_dispatch/testing/test_request.rb
@@ -10,7 +10,7 @@ def self.new(env = {})
10 10
     end
11 11
 
12 12
     def initialize(env = {})
13  
-      env = Rails.application.env_defaults.merge(env) if defined?(Rails.application)
  13
+      env = Rails.application.env_config.merge(env) if defined?(Rails.application)
14 14
       super(DEFAULT_ENV.merge(env))
15 15
 
16 16
       self.host        = 'test.host'
3  actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -727,6 +727,9 @@ def compute_public_path(source, dir, ext = nil, include_host = true)
727 727
 
728 728
           source += ".#{ext}" if rewrite_extension?(source, dir, ext)
729 729
           source  = "/#{dir}/#{source}" unless source[0] == ?/
  730
+          if controller.respond_to?(:env) && controller.env["action_dispatch.asset_path"]
  731
+            source = rewrite_asset_path(source, controller.env["action_dispatch.asset_path"])
  732
+          end
730 733
           source = rewrite_asset_path(source, config.asset_path)
731 734
 
732 735
           has_request = controller.respond_to?(:request)
23  actionpack/test/template/asset_tag_helper_test.rb
@@ -387,6 +387,15 @@ def test_string_asset_id
387 387
     assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png")
388 388
   end
389 389
 
  390
+  def test_env_asset_path
  391
+    @controller.config.asset_path = "/assets%s"
  392
+    def @controller.env; @_env ||= {} end
  393
+    @controller.env["action_dispatch.asset_path"] = "/omg%s"
  394
+
  395
+    expected_path = "/assets/omg/images/rails.png"
  396
+    assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png")
  397
+  end
  398
+
390 399
   def test_proc_asset_id
391 400
     @controller.config.asset_path = Proc.new do |asset_path|
392 401
       "/assets.v12345#{asset_path}"
@@ -396,6 +405,20 @@ def test_proc_asset_id
396 405
     assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png")
397 406
   end
398 407
 
  408
+  def test_env_proc_asset_path
  409
+    @controller.config.asset_path = Proc.new do |asset_path|
  410
+      "/assets.v12345#{asset_path}"
  411
+    end
  412
+
  413
+    def @controller.env; @_env ||= {} end
  414
+    @controller.env["action_dispatch.asset_path"] = Proc.new do |asset_path|
  415
+      "/omg#{asset_path}"
  416
+    end
  417
+
  418
+    expected_path = "/assets.v12345/omg/images/rails.png"
  419
+    assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png")
  420
+  end
  421
+
399 422
   def test_image_tag_interpreting_email_cid_correctly
400 423
     # An inline image has no need for an alt tag to be automatically generated from the cid:
401 424
     assert_equal '<img src="cid:thi%25%25sis@acontentid" />', image_tag("cid:thi%25%25sis@acontentid")
14  railties/lib/rails/application.rb
@@ -124,16 +124,12 @@ def load_console(sandbox=false)
124 124
 
125 125
     alias :build_middleware_stack :app
126 126
 
127  
-    def call(env)
128  
-      env["action_dispatch.routes"] = routes
129  
-      app.call(env.reverse_merge!(env_defaults))
130  
-    end
131  
-
132  
-    def env_defaults
133  
-      @env_defaults ||= {
  127
+    def env_config
  128
+      @env_config ||= super.merge({
134 129
         "action_dispatch.parameter_filter" => config.filter_parameters,
135  
-        "action_dispatch.secret_token" => config.secret_token
136  
-      }
  130
+        "action_dispatch.secret_token" => config.secret_token,
  131
+        "action_dispatch.asset_path" => nil
  132
+      })
137 133
     end
138 134
 
139 135
     def initializers
12  railties/lib/rails/application/configuration.rb
@@ -25,6 +25,18 @@ def initialize(*)
25 25
         @middleware = app_middleware
26 26
       end
27 27
 
  28
+      def asset_path=(value)
  29
+        action_mailer.asset_path = value if respond_to?(:action_mailer) && action_mailer
  30
+        action_controller.asset_path = value if respond_to?(:action_controller) && action_controller
  31
+        super(value)
  32
+      end
  33
+
  34
+      def asset_host=(value)
  35
+        action_mailer.asset_host = value if action_mailer
  36
+        action_controller.asset_host = value if action_controller
  37
+        super(value)
  38
+      end
  39
+
28 40
       def encoding=(value)
29 41
         @encoding = value
30 42
         if "ruby".encoding_aware?
23  railties/lib/rails/engine.rb
@@ -147,6 +147,19 @@ module Rails
147 147
   #
148 148
   # Now, Engine will get only requests that were not handled by application.
149 149
   #
  150
+  # == Asset path
  151
+  #
  152
+  # When you use engine with its own public directory, you will probably want to copy or symlink it
  153
+  # to application's public directory. To simplify generating paths for assets, you can set asset_path
  154
+  # for an Engine:
  155
+  #
  156
+  # class MyEngine::Engine < Rails::Engine
  157
+  #   config.asset_path = "/my_engine/%s"
  158
+  # end
  159
+  #
  160
+  # With such config, asset paths will be automatically modified inside Engine:
  161
+  # image_path("foo.jpg") #=> "/my_engine/images/foo.jpg"
  162
+  #
150 163
   class Engine < Railtie
151 164
     autoload :Configurable,  "rails/engine/configurable"
152 165
     autoload :Configuration, "rails/engine/configuration"
@@ -219,8 +232,14 @@ def endpoint
219 232
     end
220 233
 
221 234
     def call(env)
222  
-      env["action_dispatch.routes"] = routes
223  
-      app.call(env)
  235
+      app.call(env.merge!(env_config))
  236
+    end
  237
+
  238
+    def env_config
  239
+      @env_config ||= {
  240
+        'action_dispatch.routes' => routes,
  241
+        'action_dispatch.asset_path' => config.asset_path
  242
+      }
224 243
     end
225 244
 
226 245
     def routes
2  railties/lib/rails/engine/configuration.rb
@@ -5,7 +5,7 @@ class Engine
5 5
     class Configuration < ::Rails::Railtie::Configuration
6 6
       attr_reader :root
7 7
       attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
8  
-      attr_accessor :middleware, :plugins
  8
+      attr_accessor :middleware, :plugins, :asset_path
9 9
 
10 10
       def initialize(root=nil)
11 11
         super()
15  railties/test/application/configuration_test.rb
@@ -260,5 +260,20 @@ def index
260 260
       get "/"
261 261
       assert_not_equal res, last_response.body
262 262
     end
  263
+
  264
+    test "config.asset_path is not passed through env" do
  265
+      make_basic_app do |app|
  266
+        app.config.asset_path = "/omg%s"
  267
+      end
  268
+
  269
+      class ::OmgController < ActionController::Base
  270
+        def index
  271
+          render :inline => "<%= image_path('foo.jpg') %>"
  272
+        end
  273
+      end
  274
+
  275
+      get "/"
  276
+      assert_equal "/omg/images/foo.jpg", last_response.body
  277
+    end
263 278
   end
264 279
 end
60  railties/test/railties/engine_test.rb
@@ -199,5 +199,65 @@ class Engine < ::Rails::Engine
199 199
 
200 200
       assert_equal Rails.application.routes, env['action_dispatch.routes']
201 201
     end
  202
+
  203
+    test "it allows to set asset_path" do
  204
+      @plugin.write "lib/bukkits.rb", <<-RUBY
  205
+        class Bukkits
  206
+          class Engine < ::Rails::Engine
  207
+            config.asset_path = "/bukkits%s"
  208
+          end
  209
+        end
  210
+      RUBY
  211
+
  212
+
  213
+      @plugin.write "config/routes.rb", <<-RUBY
  214
+        Bukkits::Engine.routes.draw do
  215
+          match "/foo" => "foo#index"
  216
+        end
  217
+      RUBY
  218
+
  219
+      @plugin.write "app/controllers/foo_controller.rb", <<-RUBY
  220
+        class FooController < ActionController::Base
  221
+          def index
  222
+            render :index
  223
+          end
  224
+        end
  225
+      RUBY
  226
+
  227
+      @plugin.write "app/views/foo/index.html.erb", <<-RUBY
  228
+        <%= compute_public_path("/foo", "") %>
  229
+        <%= image_path("foo.png") %>
  230
+        <%= javascript_include_tag("foo") %>
  231
+        <%= stylesheet_link_tag("foo") %>
  232
+      RUBY
  233
+
  234
+
  235
+      app_file "app/controllers/bar_controller.rb", <<-RUBY
  236
+        class BarController < ActionController::Base
  237
+          def index
  238
+            render :index
  239
+          end
  240
+        end
  241
+      RUBY
  242
+
  243
+      app_file "app/views/bar/index.html.erb", <<-RUBY
  244
+        <%= compute_public_path("/foo", "") %>
  245
+      RUBY
  246
+
  247
+      add_to_config 'config.asset_path = "/omg%s"'
  248
+
  249
+      boot_rails
  250
+
  251
+      env = Rack::MockRequest.env_for("/foo")
  252
+      response = Bukkits::Engine.call(env)
  253
+      stripped_body = response[2].body.split("\n").map(&:strip).join("\n")
  254
+
  255
+      expected =  "/omg/bukkits/foo\n" +
  256
+                  "/omg/bukkits/images/foo.png\n" +
  257
+                  "<script src=\"/omg/bukkits/javascripts/foo.js\" type=\"text/javascript\"></script>\n" +
  258
+                  "<link href=\"/omg/bukkits/stylesheets/foo.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
  259
+      assert_equal expected, stripped_body
  260
+
  261
+    end
202 262
   end
203 263
 end

0 notes on commit a132229

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