diff --git a/README b/README
index 46c01527..20225756 100644
--- a/README
+++ b/README
@@ -11,11 +11,18 @@ and providing elegant, easily understandable, and powerful syntax.
== Using
-There are two ways to use Haml and Sass.
-The easiest is as a Rails plugin:
-Simply type ./script/plugin install http://hamptoncatlin.com/haml/stable
+There are several ways to use Haml and Sass.
+They can be used as a plugins for Rails or Merb,
+or embedded on their own in other applications.
+The first step of all of these is to install the Haml gem:
+
+ gem install haml
+
+To install Haml and Sass as a Rails plugin,
+just run haml --rails path/to/rails/app
and both Haml and Sass will be installed.
-Views with the .haml extension will automatically use Haml.
+Views with the .haml (or .html.haml for edge)
+extension will automatically use Haml.
Sass is a little more complicated;
.sass files should be placed in public/stylesheets/sass,
where they'll be automatically compiled
@@ -23,6 +30,18 @@ to corresponding CSS files in public/stylesheets when needed
(the Sass template directory is customizable...
see the Sass module docs for details).
+For Merb, .html.haml views will work without any further modification.
+To enable Sass, you also need to add it add a dependency.
+To do so, just add
+
+ dependency "haml"
+
+to config/dependencies.rb.
+Then it'll work just like it does in Rails.
+
+To use Haml and Sass programatically,
+check out the RDocs for the Haml and Sass modules.
+
== Formatting
=== Haml
diff --git a/Rakefile b/Rakefile
index 736ff1ba..a4ae223b 100644
--- a/Rakefile
+++ b/Rakefile
@@ -75,6 +75,7 @@ unless ARGV[0] == 'benchmark'
end.to_a
spec.executables = ['haml', 'html2haml', 'sass']
spec.files = FileList['lib/**/*', 'bin/*', 'test/**/*', 'Rakefile', 'init.rb'].to_a + readmes
+ spec.autorequire = ['haml', 'sass']
spec.homepage = 'http://haml.hamptoncatlin.com/'
spec.has_rdoc = true
spec.extra_rdoc_files = readmes
diff --git a/lib/haml/helpers/action_view_mods.rb b/lib/haml/helpers/action_view_mods.rb
index a3deea2c..4faa46e5 100644
--- a/lib/haml/helpers/action_view_mods.rb
+++ b/lib/haml/helpers/action_view_mods.rb
@@ -1,4 +1,5 @@
begin
+ raise LoadError if defined?(Merb::Plugins)
require 'rubygems'
require 'active_support'
require 'action_controller'
diff --git a/lib/sass.rb b/lib/sass.rb
index 2bfa7ece..7666aa37 100644
--- a/lib/sass.rb
+++ b/lib/sass.rb
@@ -407,7 +407,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
# but all constants in that file are made available in the current file.
#
# Sass looks for other Sass files in the working directory,
-# and the Sass file directory under Rails.
+# and the Sass file directory under Rails or Merb.
# Additional search directories may be specified
# using the :load_paths option (see below).
#
@@ -596,42 +596,51 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
# [:never_update] Whether the CSS files should never be updated,
# even if the template file changes.
# Setting this to true may give small performance gains.
-# It's never true by default,
-# even in production mode.
+# It always defaults to false.
+# Only has meaning within Ruby on Rails or Merb.
#
# [:always_update] Whether the CSS files should be updated every
# time a controller is accessed,
# as opposed to only when the template has been modified.
# Defaults to false.
-# Only has meaning within Ruby on Rails.
+# Only has meaning within Ruby on Rails or Merb.
#
# [:always_check] Whether a Sass template should be checked for updates every
# time a controller is accessed,
# as opposed to only when the Rails server starts.
# If a Sass template has been updated,
# it will be recompiled and will overwrite the corresponding CSS file.
-# Defaults to false if Rails is running in production mode,
-# true otherwise.
-# Only has meaning within Ruby on Rails.
+# Defaults to false in production mode, true otherwise.
+# Only has meaning within Ruby on Rails or Merb.
+#
+# [:full_exception] Whether an error in the Sass code
+# should cause Sass to provide a detailed description.
+# If set to true, the specific error will be displayed
+# along with a line number and source snippet.
+# Otherwise, a simple uninformative error message will be displayed.
+# Defaults to false in production mode, true otherwise.
+# Only has meaning within Ruby on Rails or Merb.
#
# [:template_location] The directory where Sass templates should be read from.
-# Defaults to RAILS_ROOT + "/public/stylesheets/sass".
-# Only has meaning within Ruby on Rails.
+# Defaults to RAILS_ROOT + "/public/stylesheets/sass"
+# or MERB_ROOT + "/public/stylesheets/sass".
+# Only has meaning within Ruby on Rails or Merb.
#
# [:css_location] The directory where CSS output should be written to.
-# Defaults to RAILS_ROOT + "/public/stylesheets".
-# Only has meaning within Ruby on Rails.
+# Defaults to RAILS_ROOT + "/public/stylesheets"
+# or MERB_ROOT + "/public/stylesheets".
+# Only has meaning within Ruby on Rails or Merb.
#
# [:filename] The filename of the file being rendered.
# This is used solely for reporting errors,
-# and is automatically set when using Rails.
+# and is automatically set when using Rails or Merb.
#
# [:load_paths] An array of filesystem paths which should be searched
# for Sass templates imported with the "@import" directive.
-# This defaults to the working directory and, in Rails,
-# whatever :template_location is
-# (by default RAILS_ROOT + "/public/stylesheets/sass").
+# This defaults to the working directory and, in Rails or Merb,
+# whatever :template_location is.
#
module Sass; end
require 'sass/engine'
+require 'sass/plugin' if defined?(Merb::Plugins)
diff --git a/lib/sass/plugin.rb b/lib/sass/plugin.rb
index f238de19..a7dd346a 100644
--- a/lib/sass/plugin.rb
+++ b/lib/sass/plugin.rb
@@ -1,21 +1,17 @@
require 'sass/engine'
-require 'rubygems'
-require 'action_controller'
-
-RAILS_ROOT = '. 'unless self.class.const_defined?('RAILS_ROOT')
-RAILS_ENV = 'production' unless self.class.const_defined?('RAILS_ENV')
module Sass
- # This module contains methods that ActionController calls
- # to automatically update Sass templates that need updating.
- # It wasn't designed to be used outside of the context of ActionController.
+ # This module contains methods to aid in using Sass
+ # as a stylesheet-rendering plugin for various systems.
+ # Currently Rails/ActionController and Merb are supported out of the box.
module Plugin
class << self
@@options = {
- :template_location => RAILS_ROOT + '/public/stylesheets/sass',
- :css_location => RAILS_ROOT + '/public/stylesheets',
+ :template_location => './public/stylesheets/sass',
+ :css_location => './public/stylesheets',
:always_update => false,
- :always_check => RAILS_ENV != "production"
+ :always_check => true,
+ :full_exception => true
}
# Gets various options for Sass. See README for details.
@@ -79,7 +75,7 @@ module Sass
end
def exception_string(e)
- if RAILS_ENV != "production"
+ if options[:full_exception]
e_string = "#{e.class}: #{e.message}"
if e.is_a? Sass::SyntaxError
@@ -146,17 +142,5 @@ module Sass
end
end
-# This module refers to the ActionController module that's part of Ruby on Rails.
-# Sass can be used as an alternate templating engine for Rails,
-# and includes some modifications to make this more doable.
-# The documentation can be found
-# here[http://rubyonrails.org/api/classes/ActionController/Base.html].
-module ActionController
- class Base # :nodoc:
- alias_method :sass_old_process, :process
- def process(*args)
- Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
- sass_old_process(*args)
- end
- end
-end
+require 'sass/plugin/rails' if defined?(ActionController)
+require 'sass/plugin/merb' if defined?(Merb::Plugins)
diff --git a/lib/sass/plugin/merb.rb b/lib/sass/plugin/merb.rb
new file mode 100644
index 00000000..d89a9236
--- /dev/null
+++ b/lib/sass/plugin/merb.rb
@@ -0,0 +1,20 @@
+unless defined?(Sass::MERB_LOADED)
+ Sass::MERB_LOADED = true
+
+ Sass::Plugin.options.merge!(:template_location => MERB_ROOT + '/public/stylesheets/sass',
+ :css_location => MERB_ROOT + '/public/stylesheets',
+ :always_check => MERB_ENV != "production",
+ :full_exception => MERB_ENV != "production")
+ config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {}
+ config.symbolize_keys!
+ Sass::Plugin.options.merge!(config)
+
+ class MerbHandler # :nodoc:
+ def process_with_sass(request, response)
+ Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
+ process_without_sass(request, response)
+ end
+ alias_method :process_without_sass, :process
+ alias_method :process, :process_with_sass
+ end
+end
diff --git a/lib/sass/plugin/rails.rb b/lib/sass/plugin/rails.rb
new file mode 100644
index 00000000..f21a8f2e
--- /dev/null
+++ b/lib/sass/plugin/rails.rb
@@ -0,0 +1,18 @@
+unless defined?(Sass::RAILS_LOADED)
+ Sass::RAILS_LOADED = true
+
+ Sass::Plugin.options.merge!(:template_location => RAILS_ROOT + '/public/stylesheets/sass',
+ :css_location => RAILS_ROOT + '/public/stylesheets',
+ :always_check => RAILS_ENV != "production",
+ :full_exception => RAILS_ENV != "production")
+
+ module ActionController # :nodoc:
+ class Base # :nodoc:
+ alias_method :sass_old_process, :process
+ def process(*args)
+ Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
+ sass_old_process(*args)
+ end
+ end
+ end
+end
diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb
index 064122c7..2cb9ece9 100644
--- a/test/sass/plugin_test.rb
+++ b/test/sass/plugin_test.rb
@@ -1,9 +1,14 @@
#!/usr/bin/env ruby
-RAILS_ENV = 'testing'
+MERB_ENV = RAILS_ENV = 'testing'
+RAILS_ROOT = '.'
+
require 'test/unit'
require 'fileutils'
require File.dirname(__FILE__) + '/../../lib/sass'
+require 'rubygems'
+
+require 'action_controller'
require 'sass/plugin'
class SassPluginTest < Test::Unit::TestCase
@@ -14,14 +19,7 @@ class SassPluginTest < Test::Unit::TestCase
def setup
FileUtils.mkdir File.dirname(__FILE__) + '/tmp'
- Sass::Plugin.options = {
- :template_location => File.dirname(__FILE__) + '/templates',
- :css_location => File.dirname(__FILE__) + '/tmp',
- :style => :compact,
- :load_paths => [File.dirname(__FILE__) + '/results'],
- }
- Sass::Plugin.options[:always_update] = true
-
+ set_plugin_opts
Sass::Plugin.update_stylesheets
end
@@ -56,7 +54,7 @@ class SassPluginTest < Test::Unit::TestCase
assert !Sass::Plugin.stylesheet_needs_update?('import')
end
- def test_exception_handling
+ def test_full_exception_handling
File.delete(tempfile_loc('bork'))
Sass::Plugin.update_stylesheets
File.open(tempfile_loc('bork')) do |file|
@@ -65,18 +63,18 @@ class SassPluginTest < Test::Unit::TestCase
File.delete(tempfile_loc('bork'))
end
- def test_production_exception_handling
- Sass.const_set('RAILS_ENV', 'production')
+ def test_nonfull_exception_handling
+ Sass::Plugin.options[:full_exception] = false
File.delete(tempfile_loc('bork'))
Sass::Plugin.update_stylesheets
assert_equal("/* Internal stylesheet error */", File.read(tempfile_loc('bork')))
File.delete(tempfile_loc('bork'))
- Sass::Plugin.const_set('RAILS_ENV', 'testing')
+ Sass::Plugin.options[:full_exception] = true
end
- def test_controller_process
+ def test_rails_update
File.delete(tempfile_loc('basic'))
assert Sass::Plugin.stylesheet_needs_update?('basic')
@@ -85,6 +83,26 @@ class SassPluginTest < Test::Unit::TestCase
assert !Sass::Plugin.stylesheet_needs_update?('basic')
end
+ def test_merb_update
+ begin
+ require 'merb'
+ rescue LoadError
+ puts "\nmerb couldn't be loaded, skipping a test"
+ return
+ end
+
+ require 'sass/plugin/merb'
+ MerbHandler.send(:define_method, :process_without_sass) { |*args| }
+ set_plugin_opts
+
+ File.delete(tempfile_loc('basic'))
+ assert Sass::Plugin.stylesheet_needs_update?('basic')
+
+ MerbHandler.new('.').process nil, nil
+
+ assert !Sass::Plugin.stylesheet_needs_update?('basic')
+ end
+
def test_doesnt_render_partials
assert !File.exists?(tempfile_loc('_partial'))
end
@@ -109,6 +127,16 @@ class SassPluginTest < Test::Unit::TestCase
def result_loc(name)
File.dirname(__FILE__) + "/results/#{name}.css"
end
+
+ def set_plugin_opts
+ Sass::Plugin.options = {
+ :template_location => File.dirname(__FILE__) + '/templates',
+ :css_location => File.dirname(__FILE__) + '/tmp',
+ :style => :compact,
+ :load_paths => [File.dirname(__FILE__) + '/results'],
+ :always_update => true,
+ }
+ end
end
module Sass::Plugin