diff options
Diffstat (limited to 'actionpack/lib/abstract_controller')
-rw-r--r-- | actionpack/lib/abstract_controller/helpers.rb | 10 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/layouts.rb | 33 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/rendering.rb | 64 |
3 files changed, 67 insertions, 40 deletions
diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index f875213afb..53cf6b3931 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -6,16 +6,10 @@ module AbstractController include Rendering - def self.next_serial - @helper_serial ||= 0 - @helper_serial += 1 - end - included do - class_attribute :_helpers, :_helper_serial + class_attribute :_helpers delegate :_helpers, :to => :'self.class' self._helpers = Module.new - self._helper_serial = ::AbstractController::Helpers.next_serial end module ClassMethods @@ -95,8 +89,6 @@ module AbstractController # helper(:three, BlindHelper) { def mice() 'mice' end } # def helper(*args, &block) - self._helper_serial = AbstractController::Helpers.next_serial + 1 - modules_for_helpers(args).each do |mod| add_template_helper(mod) end diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 95a6101109..319472c937 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/module/remove_method" + module AbstractController # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in # repeated setups. The inclusion pattern has pages that look like this: @@ -182,7 +184,9 @@ module AbstractController # # ==== Returns # Boolean:: True if the action has a layout, false otherwise. - def _action_has_layout? + def action_has_layout? + return unless super + conditions = _layout_conditions if only = conditions[:only] @@ -237,6 +241,8 @@ module AbstractController # name, return that string. Otherwise, use the superclass' # layout (which might also be implied) def _write_layout_method + remove_possible_method(:_layout) + case defined?(@_layout) ? @_layout : nil when String self.class_eval %{def _layout; #{@_layout.inspect} end} @@ -284,15 +290,20 @@ module AbstractController layout = options.key?(:layout) ? options.delete(:layout) : :default value = _layout_for_option(layout) options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value - - # TODO Layout for partials should be handled here, because inside the - # partial renderer it looks for the layout as a partial. - if options.key?(:partial) && options[:layout] - options[:layout] = view_context.find_layout(options[:layout]) - end end end + attr_writer :action_has_layout + + def initialize(*) + @action_has_layout = true + super + end + + def action_has_layout? + @action_has_layout + end + private # This will be overwritten by _write_layout_method @@ -332,13 +343,13 @@ module AbstractController # Template:: The template object for the default layout (or nil) def _default_layout(require_layout = false) begin - layout_name = _layout if _action_has_layout? + layout_name = _layout if action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" end - if require_layout && _action_has_layout? && !layout_name + if require_layout && action_has_layout? && !layout_name raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end @@ -349,9 +360,5 @@ module AbstractController def _include_layout?(options) (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) end - - def _action_has_layout? - true - end end end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 16664098e5..b251bd6405 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -32,7 +32,6 @@ module AbstractController module Rendering extend ActiveSupport::Concern - include AbstractController::Assigns include AbstractController::ViewPaths # Overwrite process to setup I18n proxy. @@ -43,17 +42,48 @@ module AbstractController I18n.config = old_config end + module ClassMethods + def view_context_class + @view_context_class ||= begin + controller = self + Class.new(ActionView::Base) do + if controller.respond_to?(:_helpers) + include controller._helpers + + if controller.respond_to?(:_router) + include controller._router.url_helpers + end + + # TODO: Fix RJS to not require this + self.helpers = controller._helpers + end + end + end + end + end + + attr_writer :view_context_class + + def view_context_class + @view_context_class || self.class.view_context_class + end + + def initialize(*) + @view_context_class = nil + super + end + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: - # View.for_controller[controller] + # View.new[lookup_context, assigns, controller] # Create a new ActionView instance for a controller - # View#render_template[options] + # View#render[options] # Returns String with the rendered template # # Override this method in a module to change the default behavior. def view_context - @_view_context ||= ActionView::Base.for_controller(self) + view_context_class.new(lookup_context, view_assigns, self) end # Normalize arguments, options and then delegates render_to_body and @@ -76,13 +106,12 @@ module AbstractController # :api: plugin def render_to_string(options={}) _normalize_options(options) - AbstractController::Rendering.body_to_s(render_to_body(options)) + render_to_body(options) end # Find and renders a template based on the options given. # :api: private def _render_template(options) #:nodoc: - _evaluate_assigns(view_context) view_context.render(options) end @@ -91,20 +120,19 @@ module AbstractController controller_path end - # Return a string representation of a Rack-compatible response body. - def self.body_to_s(body) - if body.respond_to?(:to_str) - body - else - strings = [] - body.each { |part| strings << part.to_s } - body.close if body.respond_to?(:close) - strings.join - end - end - private + # This method should return a hash with assigns. + # You can overwrite this configuration per controller. + # :api: public + def view_assigns + hash = {} + variables = instance_variable_names + variables -= protected_instance_variables if respond_to?(:protected_instance_variables) + variables.each { |name| hash[name.to_s[1..-1]] = instance_variable_get(name) } + hash + end + # Normalize options by converting render "foo" to render :action => "foo" and # render "foo/bar" to render :file => "foo/bar". def _normalize_args(action=nil, options={}) |