diff --git a/CHANGELOG.md b/CHANGELOG.md index d25d6d13..77fdb141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,9 @@ * Add command-line option to suppress script evaluation. +* It's now possible to use Rails's asset helpers inside the Sass and SCSS + filters. + ## 3.1.6 * In indented mode, don't reindent buffers that contain preserved tags, and diff --git a/lib/haml/filters.rb b/lib/haml/filters.rb index 268eedee..17dd23ca 100644 --- a/lib/haml/filters.rb +++ b/lib/haml/filters.rb @@ -58,6 +58,19 @@ module Haml filter end + # Removes a filter from Haml. If the filter was removed, it returns + # the that was remove Module upon success, or nil on failure. If you try + # to redefine a filter, Haml will raise an error. Use this method first to + # explicitly remove the filter before redefining it. + # @return Module The filter module that has been removed + # @since 3.2.0 + def remove_filter(name) + defined.delete name.downcase + if constants.map(&:to_s).include?(name.to_s) + remove_const name.to_sym + end + end + # The base module for Haml filters. # User-defined filters should be modules including this module. # The name of the filter is taken by downcasing the module name. diff --git a/lib/haml/railtie.rb b/lib/haml/railtie.rb index 7b824b3f..ec4bef90 100644 --- a/lib/haml/railtie.rb +++ b/lib/haml/railtie.rb @@ -7,5 +7,15 @@ if defined?(ActiveSupport) end end +module Haml + class Railtie < ::Rails::Railtie + initializer :haml do |app| + if defined?(::Sass::Rails) && app.config.assets.enabled + require "haml/sass_rails_filter" + end + end + end +end + require "haml/helpers/safe_erubis_template" Haml::Filters::Erb.template_class = Haml::SafeErubisTemplate \ No newline at end of file diff --git a/lib/haml/sass_rails_filter.rb b/lib/haml/sass_rails_filter.rb new file mode 100644 index 00000000..9d3ef29c --- /dev/null +++ b/lib/haml/sass_rails_filter.rb @@ -0,0 +1,33 @@ +module Haml + module Filters + # This is an extension of Sass::Rails's SassTemplate class that allows + # Rails's asset helpers to be used inside Haml Sass filter. + class SassRailsTemplate < ::Sass::Rails::SassTemplate + def render(scope=Object.new, locals={}, &block) + scope = ::Rails.application.assets.context_class.new(::Rails.application.assets, "/", "/") + super + end + + def sass_options(scope) + options = super + options[:custom][:resolver] = ::ActionView::Base.new + options + end + end + + # This is an extension of Sass::Rails's SassTemplate class that allows + # Rails's asset helpers to be used inside a Haml SCSS filter. + class ScssRailsTemplate < SassRailsTemplate + self.default_mime_type = 'text/css' + + def syntax + :scss + end + end + + remove_filter :Sass + remove_filter :Scss + register_tilt_filter "Sass", :extend => "Css", :template_class => SassRailsTemplate + register_tilt_filter "Scss", :extend => "Css", :template_class => ScssRailsTemplate + end +end \ No newline at end of file diff --git a/test/filters_test.rb b/test/filters_test.rb index d4dbe1d3..2914511b 100644 --- a/test/filters_test.rb +++ b/test/filters_test.rb @@ -7,7 +7,7 @@ class FiltersTest < MiniTest::Unit::TestCase Module.new {def self.name; "Foo::Bar"; end; include Haml::Filters::Base} assert Haml::Filters.defined.has_key? "bar" ensure - Haml::Filters.defined.delete "bar" + Haml::Filters.remove_filter "Bar" end end @@ -19,8 +19,7 @@ class FiltersTest < MiniTest::Unit::TestCase end end ensure - Haml::Filters.defined.delete "foo" - Haml::Filters.send :remove_const, :Foo + Haml::Filters.remove_filter "Foo" end end @@ -31,8 +30,7 @@ class FiltersTest < MiniTest::Unit::TestCase Haml::Filters.defined["textile"].template_class end ensure - Haml::Filters.defined.delete "textile" - Haml::Filters.send :remove_const, :Textile + Haml::Filters.remove_filter "Textile" end end @@ -43,8 +41,7 @@ class FiltersTest < MiniTest::Unit::TestCase Haml::Filters.defined["maruku"].template_class end ensure - Haml::Filters.defined.delete "maruku" - Haml::Filters.send :remove_const, :Maruku + Haml::Filters.remove_filter "Maruku" end end @@ -108,8 +105,7 @@ class FiltersTest < MiniTest::Unit::TestCase haml = ":foo" assert_equal "foobar\n", render(haml) ensure - Haml::Filters.defined.delete "foo" - Haml::Filters.send :remove_const, :Foo + Haml::Filters.remove_filter "Foo" end end