Created
March 25, 2011 21:18
-
-
Save digitaljhelms/887650 to your computer and use it in GitHub Desktop.
CGI wrapper around Sass, written in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# This is a simple CGI wrapper around Sass. | |
# | |
# Copy it into a directory on your site with CGI enabled. When invoked, the | |
# script will search its directory and parent directories for a YAML file named | |
# "config/sass.yml" in order to load configuration information. | |
# | |
# If you set the environment variable "sass_generate_output_file" to | |
# "true" the concatenation will be cached to disk. Use it in conjunction with | |
# URL rewriting to cache your Sass output on the first request. | |
# | |
# Assuming a site layout like this: | |
# | |
# mysite/ | |
# config/ | |
# sass.yml | |
# css/ | |
# mysite.css | |
# ... | |
# public/ | |
# index.html | |
# nph-sass.cgi (this file) | |
# vendor/ | |
# sass/ | |
# mysite.scss | |
# reset.scss | |
# | |
# mysite/config/sass.yml might look like this: | |
# | |
# :source_path: vendor/sass/ecom.scss | |
# :output_file: htdocs/css/ecom.css | |
# :load_path: | |
# - vendor/sass | |
# :style: expanded | |
# :syntax: scss | |
# | |
# The <link> tag in mysite/public/index.html could look like this: | |
# | |
# <link rel="stylesheet" type="text/css" href="sass.css" /> | |
# | |
# And you might have the following Apache configuration: | |
# | |
# <VirtualHost ...> | |
# ServerName mysite.example.org | |
# DocumentRoot "/path/to/mysite/public" | |
# | |
# <Directory "/path/to/mysite/public"> | |
# Options +ExecCGI +FollowSymLinks | |
# AddHandler cgi-script .cgi | |
# | |
# RewriteEngine on | |
# RewriteCond /sass.css !-f | |
# RewriteRule ^sass\.css /nph-sass.cgi [P,L] | |
# </Directory> | |
# </VirtualHost> | |
# | |
# All requests to /sass.css will transparently proxy /nph-sass.cgi if | |
# mysite/public/sass.css does not exist. In production, you can add | |
# | |
# SetEnv sass_generate_output_file true | |
# | |
# to your Apache configuration and mysites/public/sass.css will be cached | |
# on the first request to /sass.css. | |
require "yaml" | |
require "fileutils" | |
def respond_with(options = {}) | |
options = { :code => 200, :content => "", :type => "text/plain" }.merge(options) | |
print "HTTP/1.0 #{options[:code]}\r\n" | |
print "Content-Type: #{options[:type]}\r\n" | |
print "Content-Length: #{options[:content].length}\r\n" | |
print "\r\n#{options[:content]}" | |
$stdout.flush | |
exit! | |
end | |
def search_upwards_for(filename) | |
pwd = original_pwd = Dir.pwd | |
loop do | |
return File.expand_path(filename) if File.file?(filename) | |
Dir.chdir("..") | |
respond_with(:code => 500, :content => "couldn't find "+filename) if Dir.pwd == pwd | |
pwd = Dir.pwd | |
end | |
ensure | |
Dir.chdir(original_pwd) | |
end | |
def generate_output_file? | |
(ENV["REDIRECT_sass_generate_output_file"] || ENV["sass_generate_output_file"]) =~ /true/i | |
end | |
configuration_file = search_upwards_for("config/sass.yml") | |
sass_root = File.dirname(File.dirname(configuration_file)) | |
configuration = YAML.load(IO.read(configuration_file)) | |
begin | |
if File.directory?(sass_dir = File.join(sass_root, "vendor/gems/sass/lib")) | |
$:.unshift sass_dir | |
elsif File.directory?(sass_dir = File.join(sass_root, "vendor/sass/lib")) | |
$:.unshift sass_dir | |
else | |
require "rubygems" | |
end | |
require "sass" | |
rescue Exception => e | |
respond_with(:code => 500, :content => "couldn't find sass: #{e}") | |
end | |
begin | |
sass_path = File.join(sass_root, configuration[:source_path]) | |
output_path = File.join(sass_root, configuration[:output_file]) | |
load_paths = configuration[:load_path].map { |p| File.join(sass_root, p) } | |
tmpl = IO.read(sass_path) | |
engine = Sass::Engine.new(tmpl, | |
:load_paths => load_paths, | |
:style => configuration[:style], | |
:syntax => :scss | |
) | |
css_text = engine.render | |
if generate_output_file? | |
out_file = File.new(output_path, "w+") | |
out_file.write(css_text) | |
end | |
respond_with(:content => css_text, :type => "text/css") | |
rescue Exception => e | |
respond_with(:code => 500, :content => "couldn't generate css: #{e}") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment