diff --git a/doc-src/HAML_CHANGELOG.md b/doc-src/HAML_CHANGELOG.md
index bbf5d60905..036070a98a 100644
--- a/doc-src/HAML_CHANGELOG.md
+++ b/doc-src/HAML_CHANGELOG.md
@@ -8,6 +8,10 @@
* Add a railtie so Haml and Sass will be automatically loaded in Rails 3.
Thanks to [Daniel Neighman](http://pancakestacks.wordpress.com/).
+* Add a deprecation message for using `-` with methods like `form_for`
+ that return strings in Rails 3.
+ This is [the same deprecation that exists in Rails 3](http://github.com/rails/rails/commit/9de83050d3a4b260d4aeb5d09ec4eb64f913ba64).
+
## 2.2.21
[Tagged on GitHub](http://github.com/nex3/haml/commit/2.2.21).
diff --git a/lib/haml/template/plugin.rb b/lib/haml/template/plugin.rb
index 0a8ce842ea..7a0c5d7546 100644
--- a/lib/haml/template/plugin.rb
+++ b/lib/haml/template/plugin.rb
@@ -33,6 +33,37 @@ def cache_fragment(block, name = {}, options = nil)
end
end
end
+
+ # Rails 3.0 prints a deprecation warning when block helpers
+ # return strings that go unused.
+ # We want to print the same deprecation warning,
+ # so we have to compile in a method call to check for it.
+ #
+ # I don't like having this in the precompiler pipeline,
+ # and I'd like to get rid of it once Rails 3.1 is well-established.
+ if defined?(ActionView::OutputBuffer) &&
+ Haml::Util.has?(:instance_method, ActionView::OutputBuffer, :append_if_string=)
+ module Precompiler
+ def push_silent_with_haml_block_deprecation(text, *args)
+ unless block_opened? && text =~ ActionView::Template::Handlers::Erubis::BLOCK_EXPR
+ return push_silent_without_haml_block_deprecation(text, *args)
+ end
+
+ push_silent_without_haml_block_deprecation("_hamlout.append_if_string= #{text}", *args)
+ end
+ alias_method :push_silent_without_haml_block_deprecation, :push_silent
+ alias_method :push_silent, :push_silent_with_haml_block_deprecation
+ end
+
+ class Buffer
+ def append_if_string=(value)
+ if value.is_a?(String) && !value.is_a?(ActionView::NonConcattingString)
+ ActiveSupport::Deprecation.warn("- style block helpers are deprecated. Please use =", caller)
+ buffer << value
+ end
+ end
+ end
+ end
end
if defined? ActionView::Template and ActionView::Template.respond_to? :register_template_handler
diff --git a/test/haml/template_test.rb b/test/haml/template_test.rb
index d753327a8d..3fdf701fa8 100755
--- a/test/haml/template_test.rb
+++ b/test/haml/template_test.rb
@@ -250,6 +250,28 @@ def test_exceptions_should_work_correctly
end
end
+ if defined?(ActionView::OutputBuffer) &&
+ Haml::Util.has?(:instance_method, ActionView::OutputBuffer, :append_if_string=)
+ def test_av_block_deprecation_warning
+ assert_warning(/^DEPRECATION WARNING: - style block helpers are deprecated\. Please use =\./) do
+ assert_equal <
+ Title:
+
+ Body:
+
+
+HTML
+- form_for :article, @article, :url => '' do |f|
+ Title:
+ = f.text_field :title
+ Body:
+ = f.text_field :body
+HAML
+ end
+ end
+ end
+
## XSS Protection Tests
# In order to enable these, either test against Rails 3.0
diff --git a/test/test_helper.rb b/test/test_helper.rb
index b2147310ee..bf835f8e10 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -24,7 +24,12 @@ def clean_up_sassc
def assert_warning(message)
the_real_stderr, $stderr = $stderr, StringIO.new
yield
- assert_equal message.strip, $stderr.string.strip
+
+ if message.is_a?(Regexp)
+ assert_match message, $stderr.string.strip
+ else
+ assert_equal message.strip, $stderr.string.strip
+ end
ensure
$stderr = the_real_stderr
end