From a26aff7bb19cd5b3c8a419626574872e8c62f511 Mon Sep 17 00:00:00 2001 From: Chris Kalafarski Date: Sun, 18 Jan 2009 20:44:41 -0500 Subject: [PATCH] add content_tag_if --- actionpack/lib/action_view/helpers/tag_helper.rb | 38 ++++++++++++++++++++++ actionpack/test/template/tag_helper_test.rb | 12 +++++++ 2 files changed, 50 insertions(+), 0 deletions(-) diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index af8c4d5..3cd7701 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -79,6 +79,44 @@ module ActionView end end + # Works much like the standard content_tag, but will pick between the specified options depending on whether the + # provided condition is met. This can be used, for instance, to easily switch between classes on an HTML + # element depending on a given value or the current action or controller. + # + # ==== Options + # Options is required, and can be defined as in content_tag for attributes that do not change with the +condition+. For those + # +options+ that will switch, either an array or hash can be passed. With an array, the first value will be used + # when +condition+ is true, and the last will be used when it is not. With a hash, the keys :if and :else are + # used to define the binary options. + # + # ==== Examples + # content_tag_if(true, :p, 'Hello world!', :class => ['when-true', 'when-false']) + # # =>

Hello world!

+ # content_tag_if(false, :p, 'Hello world!', :class => ['when-true', 'when-false']) + # # =>

Hello world!

+ # + # # on /books/10/edit + # <% content_tag_if(current_page?(:controller => 'books'), :li, :id => 'book-nav', :class => { :if => 'current', :else => '' }) do -%> + # <%= link_to 'Book list', books_path %> + # <% end -%> + # # =>
  • Book list
  • + def content_tag_if(condition, name, content_or_options_with_block, options = nil, escape = true, &block) + + options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) if block_given? + + options.each do |option, values| + options[option] = case values + when Array then values.send(condition ? "first" : "last") + when Hash then ((values[:if] && values[:else]) ? values[(condition ? :if : :else)] : values.to_s) + else values.to_s + end + end + + content_or_options_with_block, options = options, nil if block_given? + + content_tag(name, content_or_options_with_block, options, escape, &block) + end + # Returns a CDATA section with the given +content+. CDATA sections # are used to escape blocks of text containing characters which would # otherwise be recognized as markup. CDATA sections begin with the string diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index ef88cae..56d592a 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -70,6 +70,18 @@ class TagHelperTest < ActionView::TestCase content_tag("p") { concat content_tag("b", "Hello") } assert_equal '

    Hello

    ', output_buffer end + + def test_content_tag_if_when_condition_is_met + assert_equal %(

    Hello world!

    ), content_tag_if(true, :p, 'Hello world!', :class => ['when-true', 'when-false']) + assert_equal %(

    Hello world!

    ), content_tag_if(true, :p, 'Hello world!', :id => 'the_id', :class => ['when-true', 'when-false']) + assert_equal %(

    Hello world!

    ), content_tag_if(true, :p, 'Hello world!', :class => {:if => 'when-true', :else => 'when-false'}) + end + + def test_content_tag_if_when_condition_is_not_met + assert_equal %(

    Hello world!

    ), content_tag_if(false, :p, 'Hello world!', :class => ['when-true', 'when-false']) + assert_equal %(

    Hello world!

    ), content_tag_if(false, :p, 'Hello world!', :id => 'the_id', :class => ['when-true', 'when-false']) + assert_equal %(

    Hello world!

    ), content_tag_if(false, :p, 'Hello world!', :class => {:if => 'when-true', :else => 'when-false'}) + end def test_cdata_section assert_equal "]]>", cdata_section("") -- 1.6.1