In one hand, I have a mountable engine let's say Front Front contain my assets and couple of pages It's isolated from MainApp. I don't want it to touch the main app.
In the other hand I want my MainApp using layout and partial of the Front. So I setup the layout this way :
class ApplicationController < ActionController::Base
layout 'front/application'
end
But the front/application refer to engine partial directly, because of isolation, like this
render 'header' # front/ prefix is not required
So the MainApp views try to load app/views/application/header instead of app/views/front/application/header
To fixe this I put a prepend_view_path like this :
class ApplicationController < ActionController::Base
layout 'front/application'
before_filter :prepend_front
protected
def prepend_front
prepend_view_path "app/views/front"
end
end
But this doesn't work because engine path point into the vendor. The engine add it self this to the prepend path list : ~/main_app/vendor/private_gems/front-0.0.2/app/views And my preprend_front method create this : ~/main_app/app/views/front
I tryed to prepend by force the correct path (but it looks so dirty) :
prepend_view_path "#{Rails.root}/vendor/private_gems/front-0.0.2/app/views/front"
I doesn't work, just crash the app ...
And I'm stuck here. Maybe my design is wrong?
Well, simply put a Rails engine is the miniature edition of a Rails application. It comes with an app folder, including controllers, models, views, routes, migrations... The difference though is, that an engine won't work on its own.
mount is used to mount another application (basically rack application) or rails engines to be used within the current application.
The answer from Jack is perfect except if you want to do this inside the Rails engine (for example if your engine itself has 'themes' that require a different load path). In this case the prepend_path and append_path are not appropriate since you are going to want to insert your new load path before the engines default load path but after the applications load path.
A solution to this (only tested in Rails 3.2) is to add the following to your engines /lib/my_engine.rb file:
config.after_initialize do
my_engine_root = MyEngine::Engine.root.to_s
paths = ActionController::Base.view_paths.collect{|p| p.to_s}
paths = paths.insert(paths.index(my_engine_root + '/app/views'), my_engine_root + '/app/views/themes/my_theme')
ActionController::Base.view_paths = paths
end
The new load path my_engine_root + '/app/views/themes/my_theme'
will now be just before your engines standard load path my_engine_root + '/app/views'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With