[Haml] Compatibility with the latest Rails 3 helper changes.

Closes gh-101
This commit is contained in:
Nathan Weizenbaum 2010-03-12 21:31:32 -08:00
parent 4bdb076b3d
commit 5aa72acb85
9 changed files with 192 additions and 39 deletions

View File

@ -15,6 +15,12 @@
* Make the error message for `- end` a little more intuitive based on user feedback.
* Compatibility with methods like `form_for`
that return strings rather than concatenate to the template in Rails 3.
* Add a {Haml::Helpers#with_tabs with_tabs} helper,
which sets the indentation level for the duration of a block.
## 2.2.20
[Tagged on GitHub](http://github.com/nex3/haml/commit/2.2.20).

View File

@ -234,6 +234,33 @@ MESSAGE
haml_buffer.tabulation -= i
end
# Sets the number of tabs the buffer automatically adds
# to the lines of the template,
# but only for the duration of the block.
# For example:
#
# %h1 foo
# - with_tabs(2) do
# %p bar
# %strong baz
#
# Produces:
#
# <h1>foo</h1>
# <p>bar</p>
# <strong>baz</strong>
#
#
# @param i [Fixnum] The number of tabs to use
# @yield [] A block in which the indentation will be `i` spaces
def with_tabs(i)
old_tabs = haml_buffer.tabulation
haml_buffer.tabulation = i
yield
ensure
haml_buffer.tabulation = old_tabs
end
# Surrounds a block of Haml code with strings,
# with no whitespace in between.
# For example:

View File

@ -131,13 +131,74 @@ module ActionView
end
end
module FormTagHelper
def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
if is_haml?
if block_given?
if Haml::Util.ap_geq_3?
module FormTagHelper
def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
if is_haml?
if block_given?
oldproc = proc
proc = haml_bind_proc do |*args|
concat "\n"
with_tabs(1) {oldproc.call(*args)}
end
end
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
res << "\n" if block_given?
res
else
form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
end
end
alias_method :form_tag_without_haml, :form_tag
alias_method :form_tag, :form_tag_with_haml
end
module FormHelper
def form_for_with_haml(object_name, *args, &proc)
if block_given? && is_haml?
oldproc = proc
proc = haml_bind_proc do |*args|
with_tabs(1) {oldproc.call(*args)}
end
end
res = form_for_without_haml(object_name, *args, &proc)
res << "\n" if block_given? && is_haml?
res
end
alias_method :form_for_without_haml, :form_for
alias_method :form_for, :form_for_with_haml
end
else
module FormTagHelper
def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
if is_haml?
if block_given?
oldproc = proc
proc = haml_bind_proc do |*args|
concat "\n"
tab_up
oldproc.call(*args)
tab_down
concat haml_indent
end
concat haml_indent
end
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
concat "\n" if block_given?
res
else
form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
end
end
alias_method :form_tag_without_haml, :form_tag
alias_method :form_tag, :form_tag_with_haml
end
module FormHelper
def form_for_with_haml(object_name, *args, &proc)
if block_given? && is_haml?
oldproc = proc
proc = haml_bind_proc do |*args|
concat "\n"
tab_up
oldproc.call(*args)
tab_down
@ -145,34 +206,12 @@ module ActionView
end
concat haml_indent
end
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
concat "\n" if block_given?
res
else
form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
form_for_without_haml(object_name, *args, &proc)
concat "\n" if block_given? && is_haml?
end
alias_method :form_for_without_haml, :form_for
alias_method :form_for, :form_for_with_haml
end
alias_method :form_tag_without_haml, :form_tag
alias_method :form_tag, :form_tag_with_haml
end
module FormHelper
def form_for_with_haml(object_name, *args, &proc)
if block_given? && is_haml?
oldproc = proc
proc = haml_bind_proc do |*args|
tab_up
oldproc.call(*args)
tab_down
concat haml_indent
end
concat haml_indent
end
form_for_without_haml(object_name, *args, &proc)
concat "\n" if block_given? && is_haml?
end
alias_method :form_for_without_haml, :form_for
alias_method :form_for, :form_for_with_haml
end
end
end

View File

@ -97,6 +97,14 @@ end
module ActionView
module Helpers
module CaptureHelper
def with_output_buffer_with_haml_xss(*args, &block)
Haml::Util.html_safe(with_output_buffer_without_haml_xss(*args, &block))
end
alias_method :with_output_buffer_without_haml_xss, :with_output_buffer
alias_method :with_output_buffer, :with_output_buffer_with_haml_xss
end
module FormTagHelper
def form_tag_with_haml_xss(*args, &block)
Haml::Util.html_safe(form_tag_without_haml_xss(*args, &block))
@ -105,6 +113,14 @@ module ActionView
alias_method :form_tag, :form_tag_with_haml_xss
end
module FormHelper
def form_for_with_haml_xss(*args, &block)
Haml::Util.html_safe(form_for_without_haml_xss(*args, &block))
end
alias_method :form_for_without_haml_xss, :form_for
alias_method :form_for, :form_for_with_haml_xss
end
module TextHelper
def concat_with_haml_xss(string)
if is_haml?

View File

@ -157,6 +157,31 @@ module Haml
return nil
end
# Returns whether this environment is using ActionPack
# version 3.0.0 or greater.
#
# @return [Boolean]
def ap_geq_3?
# The ActionPack module is always loaded automatically in Rails >= 3
return false unless defined?(ActionPack) && defined?(ActionPack::VERSION)
version =
if defined?(ActionPack::VERSION::MAJOR)
ActionPack::VERSION::MAJOR
else
# Rails 1.2
ActionPack::VERSION::Major
end
# 3.0.0.beta1 acts more like ActionPack 2
# for purposes of this method
# (checking whether block helpers require = or -).
# This extra check can be removed when beta2 is out.
version >= 3 &&
!(defined?(ActionPack::VERSION::TINY) &&
ActionPack::VERSION::TINY == "0.beta")
end
# Returns an ActionView::Template* class.
# In pre-3.0 versions of Rails, most of these classes
# were of the form `ActionView::TemplateFoo`,

View File

@ -65,7 +65,21 @@ class HelperTest < Test::Unit::TestCase
assert_equal("foo\n bar\nbaz\n", render("foo\n- tab_up\nbar\n- tab_down\nbaz"))
assert_equal(" <p>tabbed</p>\n", render("- buffer.tabulation=5\n%p tabbed"))
end
def test_with_tabs
assert_equal(<<HTML, render(<<HAML))
Foo
Bar
Baz
Baz
HTML
Foo
- with_tabs 2 do
= "Bar\\nBaz"
Baz
HAML
end
def test_helpers_dont_leak
# Haml helpers shouldn't be accessible from ERB
render("foo")
@ -93,9 +107,16 @@ class HelperTest < Test::Unit::TestCase
def test_form_tag
# This is usually provided by ActionController::Base.
def @base.protect_against_forgery?; false; end
result = render("- form_tag 'foo' do\n %p bar\n %strong baz", :action_view)
should_be = "<form action=\"foo\" method=\"post\">\n <p>bar</p>\n <strong>baz</strong>\n</form>\n"
assert_equal(should_be, result)
assert_equal(<<HTML, render(<<HAML, :action_view))
<form action="foo" method="post">
<p>bar</p>
<strong>baz</strong>
</form>
HTML
#{rails_block_helper_char} form_tag 'foo' do
%p bar
%strong baz
HAML
end
def test_text_area
@ -114,12 +135,12 @@ class HelperTest < Test::Unit::TestCase
end
def test_content_tag_block
assert_equal(<<HTML.strip, render(<<HAML, :action_view))
assert_equal(<<HTML.strip, render(<<HAML, :action_view).strip)
<div><p>bar</p>
<strong>bar</strong>
</div>
HTML
- content_tag :div do
#{rails_block_helper_char} content_tag :div do
%p bar
%strong bar
HAML

View File

@ -70,8 +70,9 @@ class TemplateTest < Test::Unit::TestCase
end
if Haml::Util.has?(:private_method, base, :evaluate_assigns)
# Rails < 3.0
base.send(:evaluate_assigns)
else
elsif Haml::Util.has?(:private_method, base, :_evaluate_assigns_and_ivars)
# Rails 2.2
base.send(:_evaluate_assigns_and_ivars)
end
@ -338,7 +339,7 @@ HAML
<input id="article_body" name="article[body]" size="30" type="text" value="World" />
</form>
HTML
- form_for :article, @article, :url => '' do |f|
#{rails_block_helper_char} form_for :article, @article, :url => '' do |f|
Title:
= f.text_field :title
Body:

View File

@ -62,6 +62,19 @@ click
<input id="article_body" name="article[body]" size="30" type="text" value="World" />
</form>
</div>
- elsif Haml::Util.ap_geq_3?
%p
= form_tag ''
%div
= form_tag '' do
%div= submit_tag 'save'
- @foo = 'value one'
= test_partial 'partial'
= form_for :article, @article, :url => '' do |f|
Title:
= f.text_field :title
Body:
= f.text_field :body
- else
%p
= form_tag ''

View File

@ -32,4 +32,9 @@ class Test::Unit::TestCase
def silence_warnings(&block)
Haml::Util.silence_warnings(&block)
end
def rails_block_helper_char
return '=' if Haml::Util.ap_geq_3?
return '-'
end
end