diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2009-04-22 15:26:03 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2009-04-22 15:26:03 +0100 |
commit | 5f3f100ce2d689480da85abc88e5e940cf90189e (patch) | |
tree | 15c1a05a5308a9eea56d7f0889ac46d9cac5b57c /actionpack/lib/action_controller/abstract | |
parent | d758d996d1b66e2a65640f79f01ce2ac674d7ed5 (diff) | |
parent | ca49299434bc764b667cd86846d892e91a150ef3 (diff) | |
download | rails-5f3f100ce2d689480da85abc88e5e940cf90189e.tar.gz rails-5f3f100ce2d689480da85abc88e5e940cf90189e.tar.bz2 rails-5f3f100ce2d689480da85abc88e5e940cf90189e.zip |
Merge branch 'master' into active_model
Conflicts:
activeresource/lib/active_resource/validations.rb
Diffstat (limited to 'actionpack/lib/action_controller/abstract')
7 files changed, 312 insertions, 0 deletions
diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb new file mode 100644 index 0000000000..ade7719cc0 --- /dev/null +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -0,0 +1,41 @@ +module AbstractController + class Base + + attr_internal :response_body + attr_internal :response_obj + attr_internal :action_name + + def self.process(action) + new.process(action) + end + + def self.inherited(klass) + end + + def initialize + self.response_obj = {} + end + + def process(action_name) + unless respond_to_action?(action_name) + raise ActionNotFound, "The action '#{action_name}' could not be found" + end + + @_action_name = action_name + process_action + self.response_obj[:body] = self.response_body + self + end + + private + + def process_action + respond_to?(action_name) ? send(action_name) : send(:action_missing, action_name) + end + + def respond_to_action?(action_name) + respond_to?(action_name) || respond_to?(:action_missing, true) + end + + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb new file mode 100644 index 0000000000..c8b509081c --- /dev/null +++ b/actionpack/lib/action_controller/abstract/callbacks.rb @@ -0,0 +1,40 @@ +module AbstractController + module Callbacks + setup do + include ActiveSupport::NewCallbacks + define_callbacks :process_action + end + + def process_action + _run_process_action_callbacks(action_name) do + super + end + end + + module ClassMethods + def _normalize_callback_options(options) + if only = options[:only] + only = Array(only).map {|o| "action_name == :#{o}"}.join(" || ") + options[:per_key] = {:if => only} + end + if except = options[:except] + except = Array(except).map {|e| "action_name == :#{e}"}.join(" || ") + options[:per_key] = {:unless => except} + end + end + + [:before, :after, :around].each do |filter| + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{filter}_filter(*names, &blk) + options = names.last.is_a?(Hash) ? names.pop : {} + _normalize_callback_options(options) + names.push(blk) if block_given? + names.each do |name| + process_action_callback(:#{filter}, name, options) + end + end + RUBY_EVAL + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/exceptions.rb b/actionpack/lib/action_controller/abstract/exceptions.rb new file mode 100644 index 0000000000..ec4680629b --- /dev/null +++ b/actionpack/lib/action_controller/abstract/exceptions.rb @@ -0,0 +1,3 @@ +module AbstractController + class ActionNotFound < StandardError ; end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb new file mode 100644 index 0000000000..1f0b38417b --- /dev/null +++ b/actionpack/lib/action_controller/abstract/helpers.rb @@ -0,0 +1,59 @@ +module AbstractController + module Helpers + depends_on Renderer + + setup do + extlib_inheritable_accessor :master_helper_module + self.master_helper_module = Module.new + end + + # def self.included(klass) + # klass.class_eval do + # extlib_inheritable_accessor :master_helper_module + # self.master_helper_module = Module.new + # end + # end + + def _action_view + @_action_view ||= begin + av = super + av.helpers.send(:include, master_helper_module) + av + end + end + + module ClassMethods + def inherited(klass) + klass.master_helper_module = Module.new + klass.master_helper_module.__send__ :include, master_helper_module + + super + end + + def add_template_helper(mod) + master_helper_module.module_eval { include mod } + end + + def helper_method(*meths) + meths.flatten.each do |meth| + master_helper_module.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 + def #{meth}(*args, &blk) + controller.send(%(#{meth}), *args, &blk) + end + ruby_eval + end + end + + def helper(*args, &blk) + args.flatten.each do |arg| + case arg + when Module + add_template_helper(arg) + end + end + master_helper_module.module_eval(&blk) if block_given? + end + end + + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb new file mode 100644 index 0000000000..478b301a26 --- /dev/null +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -0,0 +1,82 @@ +module AbstractController + module Layouts + + depends_on Renderer + + module ClassMethods + def layout(layout) + unless [String, Symbol, FalseClass, NilClass].include?(layout.class) + raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" + end + + @_layout = layout || false # Converts nil to false + _write_layout_method + end + + def _implied_layout_name + name.underscore + end + + # Takes the specified layout and creates a _layout method to be called + # by _default_layout + # + # If the specified layout is a: + # String:: return the string + # Symbol:: call the method specified by the symbol + # false:: return nil + # none:: If a layout is found in the view paths with the controller's + # name, return that string. Otherwise, use the superclass' + # layout (which might also be implied) + def _write_layout_method + case @_layout + when String + self.class_eval %{def _layout() #{@_layout.inspect} end} + when Symbol + self.class_eval %{def _layout() #{@_layout} end} + when false + self.class_eval %{def _layout() end} + else + self.class_eval %{ + def _layout + if view_paths.find_by_parts?("#{_implied_layout_name}", formats, "layouts") + "#{_implied_layout_name}" + else + super + end + end + } + end + end + end + + def _render_template(template, options) + _action_view._render_template_with_layout(template, options[:_layout]) + end + + private + + def _layout() end # This will be overwritten + + def _layout_for_name(name) + unless [String, FalseClass, NilClass].include?(name.class) + raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}" + end + + name && view_paths.find_by_parts(name, formats, "layouts") + end + + def _default_layout(require_layout = false) + if require_layout && !_layout + raise ArgumentError, + "There was no default layout for #{self.class} in #{view_paths.inspect}" + end + + begin + layout = _layout_for_name(_layout) + rescue NameError => e + raise NoMethodError, + "You specified #{@_layout.inspect} as the layout, but no such method was found" + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/logger.rb b/actionpack/lib/action_controller/abstract/logger.rb new file mode 100644 index 0000000000..4117369bd4 --- /dev/null +++ b/actionpack/lib/action_controller/abstract/logger.rb @@ -0,0 +1,7 @@ +module AbstractController + module Logger + setup do + cattr_accessor :logger + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb new file mode 100644 index 0000000000..a86eef889e --- /dev/null +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -0,0 +1,80 @@ +require "action_controller/abstract/logger" + +module AbstractController + module Renderer + depends_on AbstractController::Logger + + setup do + attr_internal :formats + + extlib_inheritable_accessor :_view_paths + + self._view_paths ||= ActionView::PathSet.new + end + + def _action_view + @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) + end + + def render(options = {}) + self.response_body = render_to_body(options) + end + + # Raw rendering of a template to a Rack-compatible body. + # ==== + # @option _prefix<String> The template's path prefix + # @option _layout<String> The relative path to the layout template to use + # + # :api: plugin + def render_to_body(options = {}) + name = options[:_template_name] || action_name + + template = options[:_template] || view_paths.find_by_parts(name.to_s, formats, options[:_prefix]) + _render_template(template, options) + end + + # Raw rendering of a template to a string. + # ==== + # @option _prefix<String> The template's path prefix + # @option _layout<String> The relative path to the layout template to use + # + # :api: plugin + def render_to_string(options = {}) + AbstractController::Renderer.body_to_s(render_to_body(options)) + end + + def _render_template(template, options) + _action_view._render_template_with_layout(template) + end + + def view_paths() _view_paths 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 + + module ClassMethods + + def append_view_path(path) + self.view_paths << path + end + + def view_paths + self._view_paths + end + + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? + paths : ActionView::Base.process_view_paths(paths) + end + end + end +end |