aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/abstract
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-04-22 15:26:03 +0100
committerPratik Naik <pratiknaik@gmail.com>2009-04-22 15:26:03 +0100
commit5f3f100ce2d689480da85abc88e5e940cf90189e (patch)
tree15c1a05a5308a9eea56d7f0889ac46d9cac5b57c /actionpack/lib/action_controller/abstract
parentd758d996d1b66e2a65640f79f01ce2ac674d7ed5 (diff)
parentca49299434bc764b667cd86846d892e91a150ef3 (diff)
downloadrails-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')
-rw-r--r--actionpack/lib/action_controller/abstract/base.rb41
-rw-r--r--actionpack/lib/action_controller/abstract/callbacks.rb40
-rw-r--r--actionpack/lib/action_controller/abstract/exceptions.rb3
-rw-r--r--actionpack/lib/action_controller/abstract/helpers.rb59
-rw-r--r--actionpack/lib/action_controller/abstract/layouts.rb82
-rw-r--r--actionpack/lib/action_controller/abstract/logger.rb7
-rw-r--r--actionpack/lib/action_controller/abstract/renderer.rb80
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