Skip to content

Instantly share code, notes, and snippets.

@robhurring
Created March 16, 2009 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robhurring/79871 to your computer and use it in GitHub Desktop.
Save robhurring/79871 to your computer and use it in GitHub Desktop.
Rails Metal theme switcher
# 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 %>
/*
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;
}
# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment