Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6642: fragment_caching_for_non_erb_templates.2.diff

File fragment_caching_for_non_erb_templates.2.diff, 8.2 kB (added by mpalmer, 1 year ago)
  • actionpack/lib/action_controller/caching.rb

    old new  
    359359        name.is_a?(Hash) ? url_for(name).split("://").last : name 
    360360      end 
    361361 
    362       # Called by CacheHelper#cache 
    363       def cache_erb_fragment(block, name = {}, options = nil) 
    364         unless perform_caching then block.call; return end 
    365  
    366         buffer = eval(ActionView::Base.erb_variable, block.binding) 
    367362 
     363      def fragment_for(block, name = {}, options = nil) 
     364        unless perform_caching then block.call; return end 
     365        buffer = yield 
    368366        if cache = read_fragment(name, options) 
    369367          buffer.concat(cache) 
    370368        else 
     
    374372        end 
    375373      end 
    376374 
     375      # Called by CacheHelper#cache 
     376      def cache_rxml_fragment(block, name = {}, options = nil) 
     377        fragment_for(block, name, options) do 
     378          eval('xml.target!', block.binding) 
     379        end 
     380      end 
     381 
     382      # Called by CacheHelper#cache 
     383      def cache_rjs_fragment(block, name = {}, options = nil) 
     384        fragment_for(block, name, options) do 
     385          begin 
     386            debug_mode, ActionView::Base.debug_rjs = ActionView::Base.debug_rjs, false 
     387            eval('page.to_s', block.binding) 
     388          ensure 
     389            ActionView::Base.debug_rjs = debug_mode 
     390          end 
     391        end 
     392      end 
     393 
     394      # Called by CacheHelper#cache 
     395      def cache_erb_fragment(block, name = {}, options = nil) 
     396        fragment_for(block, name, options) do 
     397          eval(ActionView::Base.erb_variable, block.binding) 
     398        end 
     399      end 
     400 
    377401      def write_fragment(name, content, options = nil) 
    378402        return unless perform_caching 
    379403 
     
    618642        # ActiveRecord::Observer will mark this class as reloadable even though it should not be. 
    619643        # However, subclasses of ActionController::Caching::Sweeper should be Reloadable 
    620644        include Reloadable::Deprecated 
    621          
     645 
    622646        def before(controller) 
    623647          self.controller = controller 
    624648          callback(:before) 
  • actionpack/lib/action_view/helpers/cache_helper.rb

    old new  
    3232      #      <i>Topics listed alphabetically</i> 
    3333      #    <% end %> 
    3434      def cache(name = {}, &block) 
    35         @controller.cache_erb_fragment(block, name) 
     35        template_extension = first_render[/\.(\w+)$/, 1].to_sym 
     36        case template_extension 
     37        when :rhtml 
     38          @controller.cache_erb_fragment(block, name) 
     39        when :rjs 
     40          @controller.cache_rjs_fragment(block, name) 
     41        when :rxml 
     42          @controller.cache_rxml_fragment(block, name) 
     43        else 
     44          # do a last ditch effort for those brave souls using 
     45          # different template engines. This should give plugin 
     46          # writters a simple hook. 
     47          raise "fragment caching not supported for #{template_extension} files." unless @controller.respond_to?("cache_#{template_extension}_fragment") 
     48          @controller.send "cache_#{template_extension}_fragment", block, name 
     49        end 
    3650      end 
    3751    end 
    3852  end 
  • actionpack/test/controller/caching_test.rb

    old new  
    311311      assert File.exist?(full_path), "#{full_path.inspect} does not exist." 
    312312    end 
    313313end 
     314 
     315class FragmentCachingTestController < ActionController::Base 
     316  def some_action; end; 
     317end 
     318 
     319class FragmentCachingTest < Test::Unit::TestCase 
     320  def setup 
     321    ActionController::Base.perform_caching = true 
     322    @store = ActionController::Caching::Fragments::UnthreadedMemoryStore.new 
     323    ActionController::Base.fragment_cache_store = @store 
     324    @controller = FragmentCachingTestController.new 
     325    @params = {:controller => 'posts', :action => 'index'} 
     326    @request = ActionController::TestRequest.new 
     327    @response = ActionController::TestResponse.new 
     328    @controller.params = @params 
     329    @controller.request = @request 
     330    @controller.response = @response 
     331    @controller.send(:initialize_current_url) 
     332  end 
     333 
     334  def test_fragement_cache_key 
     335    assert_equal 'dee zsombor', @controller.fragment_cache_key('dee zsombor') 
     336    assert_equal( "test.host/fragment_caching_test/some_action", 
     337                  @controller.fragment_cache_key(:controller => 'fragment_caching_test',:action => 'some_action')) 
     338  end 
     339 
     340  def test_read_fragment__with_caching_enabled 
     341    @store.write('name', 'value') 
     342    assert_equal 'value', @controller.read_fragment('name') 
     343  end 
     344 
     345  def test_read_fragment__with_caching_disabled 
     346    ActionController::Base.perform_caching = false 
     347    @store.write('name', 'value') 
     348    assert_nil @controller.read_fragment('name') 
     349  end 
     350 
     351  def test_write_fragment__with_caching_enabled 
     352    assert_nil @store.read('name') 
     353    assert_equal 'value', @controller.write_fragment('name', 'value') 
     354    assert_equal 'value', @store.read('name') 
     355  end 
     356 
     357  def test_write_fragment__with_caching_disabled 
     358    assert_nil @store.read('name') 
     359    ActionController::Base.perform_caching = false 
     360    assert_equal nil, @controller.write_fragment('name', 'value') 
     361    assert_nil @store.read('name') 
     362  end 
     363 
     364  def test_expire_fragment__with_simple_key 
     365    @store.write('name', 'value') 
     366    @controller.expire_fragment 'name' 
     367    assert_nil @store.read('name') 
     368  end 
     369 
     370  def test_expire_fragment__with__regexp 
     371    @store.write('name', 'value') 
     372    @store.write('another_name', 'another_value') 
     373    @store.write('primalgrasp', 'will not expire ;-)') 
     374 
     375    @controller.expire_fragment /name/ 
     376 
     377    assert_nil @store.read('name') 
     378    assert_nil @store.read('another_name') 
     379    assert_equal 'will not expire ;-)', @store.read('primalgrasp') 
     380  end 
     381 
     382  def test_fragment_for__with_disabled_caching 
     383    ActionController::Base.perform_caching = false 
     384 
     385    @store.write('expensive', 'fragment content') 
     386    fragment_computed = false 
     387 
     388    buffer = 'generated till now -> ' 
     389    @controller.fragment_for(Proc.new { fragment_computed = true }, 'expensive') { buffer } 
     390 
     391    assert fragment_computed 
     392    assert_equal 'generated till now -> ', buffer 
     393  end 
     394 
     395 
     396  def test_fragment_for 
     397    @store.write('expensive', 'fragment content') 
     398    fragment_computed = false 
     399 
     400    buffer = 'generated till now -> ' 
     401    @controller.fragment_for(Proc.new { fragment_computed = true }, 'expensive') { buffer} 
     402 
     403    assert !fragment_computed 
     404    assert_equal 'generated till now -> fragment content', buffer 
     405  end 
     406 
     407  def test_cache_erb_fragment 
     408    @store.write('expensive', 'fragment content') 
     409    _erbout = 'generated till now -> ' 
     410 
     411    assert_equal( 'generated till now -> fragment content', 
     412                  @controller.cache_erb_fragment(Proc.new{ }, 'expensive')) 
     413  end 
     414 
     415  def test_cache_rxml_fragment 
     416    @store.write('expensive', 'fragment content') 
     417    xml = 'generated till now -> ' 
     418    class << xml; def target!; to_s; end; end 
     419 
     420    assert_equal( 'generated till now -> fragment content', 
     421                  @controller.cache_rxml_fragment(Proc.new{ }, 'expensive')) 
     422  end 
     423 
     424  def test_cache_rjs_fragment 
     425    @store.write('expensive', 'fragment content') 
     426    page = 'generated till now -> ' 
     427 
     428    assert_equal( 'generated till now -> fragment content', 
     429                  @controller.cache_rjs_fragment(Proc.new{ }, 'expensive')) 
     430  end 
     431 
     432  def test_cache_rjs_fragment_debug_mode_does_not_interfere 
     433    @store.write('expensive', 'fragment content') 
     434    page = 'generated till now -> ' 
     435 
     436    begin 
     437      debug_mode, ActionView::Base.debug_rjs = ActionView::Base.debug_rjs, true 
     438      assert_equal( 'generated till now -> fragment content', 
     439                    @controller.cache_rjs_fragment(Proc.new{ }, 'expensive')) 
     440      assert ActionView::Base.debug_rjs 
     441    ensure 
     442      ActionView::Base.debug_rjs = debug_mode 
     443    end 
     444  end 
     445end