Reputation: 5998
For a Rails application I am making I want to be able to switch 'themes' using a configuration file. The theme does not need to switch dynamically (while running, but will be known when the application starts).
I moved my stylesheets
directory out of my assets
directory, to a folder called : /app/themes/[themename]/assets/stylesheets
.
The idea is to have multiple folders in the /app/themes
directory, which can be used by the application.
REMARK: I didn't move my javascripts
folder from the assets folder, because I still want to use that globally.
In my layout I use the following code, to load controller specific stylesheets:
<%= stylesheet_link_tag "#{controller_name}" if MyApp::Application.assets.find_asset("#{controller_name}") %>
Of course, my application no longer knows where my assets are and it serves me a page, where the assets are not loading (because of the if
check mentioned above).
I added the following code to my config/initializers/assets.rb
to make sure it also loads the assets from the theme directory:
Dir.glob("#{Rails.root}/app/themes/#{Settings.site.theme}/assets/**/").each do |path|
Rails.application.config.assets.paths << path
end
Settings.site.theme
is a string value which is filled correctly and now the stylesheets actually load on the website. So YAY!
But here is the thing, the minute I change the config.assets.compile
to false
, it all fails (so on test and production).
MyApp::Application.assets.find_asset("#{controller_name}")
is throwing the exception undefined method
find_asset' for nil:NilClass`.
I am on Rails 5.0.0.1.
Anyone got an idea how to fix this?
Upvotes: 0
Views: 570
Reputation: 2174
I think a simpler way would be to namespace the themes under the stylesheets. That is, have a folder structure like this:
- app
- assets
- stylesheets
- theme-blue
- application.scss
- theme-red
- application.scss
- javascripts
- application.js
And then, in your layout file, you just point the stylesheet_link_tag
to theme-blue/application
, like this:
<%= stylesheet_link_tag "theme-blue/application" %>
Another way to do this is have multiple layouts, one for theme-blue
and another one for theme-red
. In the controller, do
class BlueController < ApplicationController
layout "theme_blue"
end
And the file app/views/layouts/theme_blue.html.erb
will require the right css file.
You might need to add the scss files to config/assets.rb
, but Rails will tell you if you need that.
Upvotes: 1