Skip to content

Instantly share code, notes, and snippets.

@chriseppstein
Created October 8, 2010 22:03
Show Gist options
  • Save chriseppstein/617650 to your computer and use it in GitHub Desktop.
Save chriseppstein/617650 to your computer and use it in GitHub Desktop.
module Sass::Script::Functions
def user_color
color_values = options[:custom][:user].color.
scan(/^#?(..?)(..?)(..?)$/).first.
map {|num| num.ljust(2, num).to_i(16)}
Sass::Script::Color.new(color_values)
end
end
map.stylesheet "/stylesheets/*path", :controller => "runtime_stylesheets", :action => "show"
# Note: This might not work at all -- I didn't run it or anything.
class RuntimeStylesheetsController < ApplicationController
before_filter :lookup_user
caches_action :show, :cache_path => :show, :ttl => 24.hours
def show
contents = File.read("#{Rails.root}/app/runtime_stylesheets/#{params[:path].join("/")}")
options = {:custom => {:user => @user}}
# If you're using compass & assuming you have compass-rails installed and activated in production.
options.update(Compass.configuration.to_sass_engine_options)
engine = Sass::Engine.new(contents, options)
render :text => engine.render, :content_type => "text/css"
end
private
def lookup_user
@user = User.find_by_id(session[:user_id])
render :text => "", :status => :not_found unless @user
end
def show_url
"user_stylesheets/#{@user.id}/#{params[:path].join("/")}"
end
end
body {
background-color: user-color();
}
@chriseppstein
Copy link
Author

This should probably set the content type and handle the .css extension, etc.

@benissimo
Copy link

Right, that last line of the show method could be:

render :text => Sass::Engine.new(contents, :custom => {:user => @user}).render, :content_type => "text/css"

and in your routes you'd want to include :format as part of the route to ensure it gets cached as css. I have a working version of this using caches_page.

Also note that, to use that custom user variable, your sass/scss files would need to access it via a custom function, something like:

  module Sass::Script::Functions
    def user_color
      sass_user_color = Sass::Script::String.new(options[:custom][:user].color, :string)
      assert_type sass_user_color, :String
      Sass::Script::String.new("##{sass_user_color.value}")
    end
  end

And then in your .scss:

  $user_color = user_color();

Just thought I'd add this here as the documentation on how to use custom data in a function lacks an example.

@chriseppstein
Copy link
Author

Thanks, I've updated the gist.

@benissimo
Copy link

Thanks for improving on the user_color example. Returning a Sass::Script::Color instead of a Sass::Script::String is much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment