diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index 89787727bd..a07fe2b255 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -34,17 +34,23 @@ module ActionController #:nodoc: ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views) end - def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc: + def fragment_for(name = {}, options = nil, &block) #:nodoc: if perform_caching if fragment_exist?(name, options) - buffer.safe_concat(read_fragment(name, options)) + read_fragment(name, options) else + # VIEW TODO: Make #capture usable outside of ERB + # This dance is needed because Builder can't use capture + buffer = view_context.output_buffer pos = buffer.length - block.call - write_fragment(name, buffer[pos..-1], options) + yield + fragment = buffer[pos..-1] + write_fragment(name, fragment, options) + ActionView::NonConcattingString.new(fragment) end else - block.call + ret = yield + ActiveSupport::SafeBuffer.new(ret) if ret.is_a?(String) end end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index feaf45c333..3920d8593f 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -3,6 +3,9 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' module ActionView #:nodoc: + class NonConcattingString < ActiveSupport::SafeBuffer + end + class ActionViewError < StandardError #:nodoc: end diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb index d5cc14b29a..3729d7daa8 100644 --- a/actionpack/lib/action_view/helpers/cache_helper.rb +++ b/actionpack/lib/action_view/helpers/cache_helper.rb @@ -32,7 +32,7 @@ module ActionView # Topics listed alphabetically # <% end %> def cache(name = {}, options = nil, &block) - controller.fragment_for(output_buffer, name, options, &block) + controller.fragment_for(name, options, &block) end end end diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 03c7ba5a87..b64dc1533f 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -2,22 +2,22 @@ module ActionView module Helpers # CaptureHelper exposes methods to let you extract generated markup which # can be used in other parts of a template or layout file. - # It provides a method to capture blocks into variables through capture and + # It provides a method to capture blocks into variables through capture and # a way to capture a block of markup for use in a layout through content_for. module CaptureHelper - # The capture method allows you to extract part of a template into a - # variable. You can then use this variable anywhere in your templates or layout. - # + # The capture method allows you to extract part of a template into a + # variable. You can then use this variable anywhere in your templates or layout. + # # ==== Examples # The capture method can be used in ERb templates... - # + # # <% @greeting = capture do %> # Welcome to my shiny new web page! The date and time is # <%= Time.now %> # <% end %> # # ...and Builder (RXML) templates. - # + # # @timestamp = capture do # "The current timestamp is #{Time.now}." # end @@ -33,15 +33,17 @@ module ActionView def capture(*args) value = nil buffer = with_output_buffer { value = yield *args } - buffer.presence || value + if string = buffer.presence || value and string.is_a?(String) + NonConcattingString.new(string) + end end # Calling content_for stores a block of markup in an identifier for later use. # You can make subsequent calls to the stored content in other templates or the layout # by passing the identifier as an argument to yield. - # + # # ==== Examples - # + # # <% content_for :not_authorized do %> # alert('You are not authorized to do that!') # <% end %> @@ -92,7 +94,7 @@ module ActionView # <% end %> # # <%# Add some other content, or use a different template: %> - # + # # <% content_for :navigation do %> #
Builder
\n", @store.read('views/test.host/functional_caching/formatted_fragment_cached') end - - def test_js_formatted_fragment_caching - get :formatted_fragment_cached, :format => "js" - assert_response :success - expected_body = %(title = "Hey";\n$("element_1").visualEffect("highlight");\n) + - %($("element_2").visualEffect("highlight");\nfooter = "Bye";) - assert_equal expected_body, @response.body - - assert_equal ['$("element_1").visualEffect("highlight");', '$("element_2").visualEffect("highlight");'], - @store.read('views/test.host/functional_caching/formatted_fragment_cached') - end end diff --git a/actionpack/test/fixtures/layouts/block_with_layout.erb b/actionpack/test/fixtures/layouts/block_with_layout.erb index f25b41271d..73ac833e52 100644 --- a/actionpack/test/fixtures/layouts/block_with_layout.erb +++ b/actionpack/test/fixtures/layouts/block_with_layout.erb @@ -1,3 +1,3 @@ -<% render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% "Return value should be discarded" %><% end %> +<%= render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% "Return value should be discarded" %><% end %> <%= yield %> -<% render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %> +<%= render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %> diff --git a/actionpack/test/fixtures/test/deprecated_nested_layout.erb b/actionpack/test/fixtures/test/deprecated_nested_layout.erb new file mode 100644 index 0000000000..7b6dcbb6c7 --- /dev/null +++ b/actionpack/test/fixtures/test/deprecated_nested_layout.erb @@ -0,0 +1,3 @@ +<% content_for :title, "title" -%> +<% content_for :column do -%>column<% end -%> +<% render :layout => 'layouts/column' do -%>content<% end -%> \ No newline at end of file diff --git a/actionpack/test/fixtures/test/nested_layout.erb b/actionpack/test/fixtures/test/nested_layout.erb index 7b6dcbb6c7..6078f74b4c 100644 --- a/actionpack/test/fixtures/test/nested_layout.erb +++ b/actionpack/test/fixtures/test/nested_layout.erb @@ -1,3 +1,3 @@ <% content_for :title, "title" -%> <% content_for :column do -%>column<% end -%> -<% render :layout => 'layouts/column' do -%>content<% end -%> \ No newline at end of file +<%= render :layout => 'layouts/column' do -%>content<% end -%> \ No newline at end of file diff --git a/actionpack/test/fixtures/test/using_layout_around_block.html.erb b/actionpack/test/fixtures/test/using_layout_around_block.html.erb index a93fa02c9c..3d6661df9a 100644 --- a/actionpack/test/fixtures/test/using_layout_around_block.html.erb +++ b/actionpack/test/fixtures/test/using_layout_around_block.html.erb @@ -1 +1 @@ -<% render(:layout => "layout_for_partial", :locals => { :name => "David" }) do %>Inside from block<% end %> \ No newline at end of file +<%= render(:layout => "layout_for_partial", :locals => { :name => "David" }) do %>Inside from block<% end %> \ No newline at end of file diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb index cc96a43901..b5b7ae87de 100644 --- a/actionpack/test/template/erb/tag_helper_test.rb +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -20,7 +20,7 @@ module ERBTest end class DeprecatedViewContext < ViewContext - include ActionView::Helpers::DeprecatedBlockHelpers + # include ActionView::Helpers::DeprecatedBlockHelpers end module SharedTagHelpers @@ -31,28 +31,36 @@ module ERBTest ActionView::Template::Handlers::Erubis.new(template).evaluate(context.new) end + def maybe_deprecated + if @deprecated + assert_deprecated { yield } + else + yield + end + end + test "percent equals works for content_tag and does not require parenthesis on method call" do - assert_equal "