class ActionCacheFilter #:nodoc:
def initialize(options, &block)
- @options = options
+ @cache_path, @store_options, @layout =
+ options.values_at(:cache_path, :store_options, :layout)
end
def filter(controller)
- should_continue = before(controller)
- yield if should_continue
- after(controller)
- end
-
- def before(controller)
- cache_path = ActionCachePath.new(controller, path_options_for(controller, @options.slice(:cache_path)))
+ path_options = @cache_path.respond_to?(:call) ? @cache_path.call(controller) : @cache_path
+ cache_path = ActionCachePath.new(controller, path_options || {})
- if cache = controller.read_fragment(cache_path.path, @options[:store_options])
- controller.rendered_action_cache = true
- set_content_type!(controller, cache_path.extension)
- options = { :text => cache }
- options.merge!(:layout => true) if cache_layout?
- controller.__send__(:render, options)
- false
+ if cache = controller.read_fragment(cache_path.path, @store_options)
+ controller._render_cache_fragment(cache, cache_path.extension, @layout == false)
else
- controller.action_cache_path = cache_path
+ yield
+ controller._save_fragment(cache_path.path, @layout == false, @store_options)
end
end
-
- def after(controller)
- return if controller.rendered_action_cache || !caching_allowed(controller)
- action_content = cache_layout? ? content_for_layout(controller) : controller.response.body
- controller.write_fragment(controller.action_cache_path.path, action_content, @options[:store_options])
- end
-
- private
- def set_content_type!(controller, extension)
- controller.response.content_type = Mime::Type.lookup_by_extension(extension).to_s if extension
- end
-
- def path_options_for(controller, options)
- ((path_options = options[:cache_path]).respond_to?(:call) ? path_options.call(controller) : path_options) || {}
- end
-
- def caching_allowed(controller)
- controller.request.get? && controller.response.status.to_i == 200
- end
-
- def cache_layout?
- @options[:layout] == false
- end
-
- def content_for_layout(controller)
- template = controller.view_context
- template.layout && template.instance_variable_get('@cached_content_for_layout')
- end
end