public
Last active

Rails Metal theme switcher

  • Download Gist
application.html.erb
HTML+ERB
1 2 3 4 5 6
# your applications main layout file (app/views/layouts/application.html.erb?)
# I put this after the normal stylesheet call, so our theme can override what we want instead of the entire stylesheet
<% if theme = request.env['rails.theme'] %>
<%= stylesheet_link_tag "themes/#{theme}", :media => :all %>
<% end %>
name_of_theme.css
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
RAILS_ROOT/public/stylesheets/themes/st_patricks_day.css
{{
theme=st patricks day
&begin=March 17
&end=March 18
&enabled=1
}}
*/
#header{
background:#C2DDCA url(theme_images/shamrock.png) no-repeat 25px 20px;
padding-left:50px;
}
theme.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
# app/metal/theme.rb
 
class Theme
# this is where the theme index is stored
CacheKey = 'themes'
# this is what we will look for in the layout
ThemeEnvKey = 'rails.theme'
# this is the path to your themes folder
ThemesPath = File.join(RAILS_ROOT, 'public', 'stylesheets', 'themes')
 
def self.call(env)
# Build our theme index
themes = Rails.cache.fetch(CacheKey) do
data = {}
Dir[File.join(ThemesPath, '*.css')].each do |theme|
# looks for {{ url_type_string_here }} comment meta data and parses
# it out into a hash for the theme's file name
#
# within your theme file, you would have:
# {{theme=my name&begin=DATE&end=DATE}}
# becomes
# {'theme.css' => {:theme => 'my mane', :begin => 'START_DATE', :end => 'FINISH_DATE'}}
#
# DATE is parsed so it can be any type of
# date-ish string see ActiveSupport::TimeZone#parse
begin
data[File.basename(theme)] = \
$1.split('&').inject({}) do |h, v|
s = v.split('=').map(&:strip)
h[s.first.to_sym] = s.last
h
end if File.read(theme) =~ /\{\{(.+)\}\}/m
rescue Exception => e
data[theme] = {:error => e.to_s}
end
end
data
end
 
# Set the appropriate theme
now = Time.zone.now.beginning_of_day
themes.each_pair do |file, data|
next if data.keys.include?(:enabled) and data[:enabled].to_i.zero?
next unless data.keys.include?(:begin) and data.keys.include?(:end)
 
if Time.zone.parse(data[:begin]) <= now and Time.zone.parse(data[:end]) > now
env[ThemeEnvKey] = file
break
end
end
 
# pass
Rails::Rack::Metal::NotFoundResponse
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.