aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-06-23 18:13:46 -0300
committerEmilio Tagua <miloops@gmail.com>2009-06-23 18:13:46 -0300
commitb9088dce07f8525cdb84a1312a77b81db79067d6 (patch)
tree72ace069842b074981ba814ef1c335271176ce27 /actionpack/lib
parent4864f92ee34e840307d968fa8b04972b6d786fe8 (diff)
parent4417a19b035d73eb46a5e06e296a4b1c8091bef1 (diff)
downloadrails-b9088dce07f8525cdb84a1312a77b81db79067d6.tar.gz
rails-b9088dce07f8525cdb84a1312a77b81db79067d6.tar.bz2
rails-b9088dce07f8525cdb84a1312a77b81db79067d6.zip
Merge commit 'rails/master'
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_controller/base/compatibility.rb8
-rw-r--r--actionpack/lib/action_controller/base/filter_parameter_logging.rb5
-rw-r--r--actionpack/lib/action_controller/base/flash.rb74
-rw-r--r--actionpack/lib/action_controller/base/http.rb2
-rw-r--r--actionpack/lib/action_controller/base/layouts.rb7
-rw-r--r--actionpack/lib/action_controller/base/mime_responds.rb7
-rw-r--r--actionpack/lib/action_controller/base/request_forgery_protection.rb18
-rw-r--r--actionpack/lib/action_controller/base/streaming.rb5
-rw-r--r--actionpack/lib/action_controller/base/verification.rb5
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb26
-rw-r--r--actionpack/lib/action_controller/legacy/layout.rb3
-rw-r--r--actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb3
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb14
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb10
-rw-r--r--actionpack/lib/action_view.rb29
-rw-r--r--actionpack/lib/action_view/base.rb55
-rw-r--r--actionpack/lib/action_view/helpers/active_record_helper.rb59
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb31
-rw-r--r--actionpack/lib/action_view/paths.rb2
-rw-r--r--actionpack/lib/action_view/render/partials.rb7
-rw-r--r--actionpack/lib/action_view/render/rendering.rb70
-rw-r--r--actionpack/lib/action_view/template/handlers/builder.rb3
-rw-r--r--actionpack/lib/action_view/template/handlers/rjs.rb1
-rw-r--r--actionpack/lib/action_view/template/path.rb152
-rw-r--r--actionpack/lib/action_view/template/resolver.rb150
-rw-r--r--actionpack/lib/action_view/template/template.rb4
-rw-r--r--actionpack/lib/action_view/template/text.rb2
27 files changed, 337 insertions, 415 deletions
diff --git a/actionpack/lib/action_controller/base/compatibility.rb b/actionpack/lib/action_controller/base/compatibility.rb
index 29ba43a879..cd4b72b1c6 100644
--- a/actionpack/lib/action_controller/base/compatibility.rb
+++ b/actionpack/lib/action_controller/base/compatibility.rb
@@ -118,6 +118,14 @@ module ActionController
details[:prefix] = nil if name =~ /\blayouts/
super
end
+
+ # Move this into a "don't run in production" module
+ def _default_layout(details, require_layout = false)
+ super
+ rescue ActionView::MissingTemplate
+ _find_by_parts(_layout({}), {})
+ nil
+ end
def performed?
response_body
diff --git a/actionpack/lib/action_controller/base/filter_parameter_logging.rb b/actionpack/lib/action_controller/base/filter_parameter_logging.rb
index 8370ba6fc0..26cd03f277 100644
--- a/actionpack/lib/action_controller/base/filter_parameter_logging.rb
+++ b/actionpack/lib/action_controller/base/filter_parameter_logging.rb
@@ -2,10 +2,7 @@ module ActionController
module FilterParameterLogging
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include AbstractController::Logger
- end
+ include AbstractController::Logger
included do
include InstanceMethodsForNewBase
diff --git a/actionpack/lib/action_controller/base/flash.rb b/actionpack/lib/action_controller/base/flash.rb
index 42c6e430ca..590f9be3ac 100644
--- a/actionpack/lib/action_controller/base/flash.rb
+++ b/actionpack/lib/action_controller/base/flash.rb
@@ -28,20 +28,7 @@ module ActionController #:nodoc:
module Flash
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- include Session if defined?(ActionController::Http)
-
- included do
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include InstanceMethodsForNewBase
- else
- include InstanceMethodsForBase
-
- alias_method_chain :perform_action, :flash
- alias_method_chain :reset_session, :flash
- end
- end
+ include Session
class FlashNow #:nodoc:
def initialize(flash)
@@ -148,49 +135,30 @@ module ActionController #:nodoc:
end
end
- module InstanceMethodsForBase #:nodoc:
- protected
- def perform_action_with_flash
- perform_action_without_flash
- if defined? @_flash
- @_flash.store(session)
- remove_instance_variable(:@_flash)
- end
- end
-
- def reset_session_with_flash
- reset_session_without_flash
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
+ protected
+ def process_action(method_name)
+ super
+ if defined? @_flash
+ @_flash.store(session)
+ remove_instance_variable(:@_flash)
+ end
end
- module InstanceMethodsForNewBase #:nodoc:
- protected
- def process_action(method_name)
- super
- if defined? @_flash
- @_flash.store(session)
- remove_instance_variable(:@_flash)
- end
- end
-
- def reset_session
- super
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
+ def reset_session
+ super
+ remove_instance_variable(:@_flash) if defined?(@_flash)
end
- protected
- # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
- # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
- # to put a new one.
- def flash #:doc:
- if !defined?(@_flash)
- @_flash = session["flash"] || FlashHash.new
- @_flash.sweep
- end
-
- @_flash
+ # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
+ # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
+ # to put a new one.
+ def flash #:doc:
+ if !defined?(@_flash)
+ @_flash = session["flash"] || FlashHash.new
+ @_flash.sweep
end
+
+ @_flash
+ end
end
end
diff --git a/actionpack/lib/action_controller/base/http.rb b/actionpack/lib/action_controller/base/http.rb
index 2e73561f93..ec78bc15a8 100644
--- a/actionpack/lib/action_controller/base/http.rb
+++ b/actionpack/lib/action_controller/base/http.rb
@@ -36,7 +36,7 @@ module ActionController
# ==== Returns
# String
def self.controller_path
- @controller_path ||= self.name.sub(/Controller$/, '').underscore
+ @controller_path ||= name && name.sub(/Controller$/, '').underscore
end
# Delegates to the class' #controller_path
diff --git a/actionpack/lib/action_controller/base/layouts.rb b/actionpack/lib/action_controller/base/layouts.rb
index ace4b148c9..365351b421 100644
--- a/actionpack/lib/action_controller/base/layouts.rb
+++ b/actionpack/lib/action_controller/base/layouts.rb
@@ -26,9 +26,6 @@ module ActionController
# hello world
# // The footer part of this layout
#
- # NOTE: The old notation for rendering the view from a layout was to expose the magic <tt>@content_for_layout</tt> instance
- # variable. The preferred notation now is to use <tt>yield</tt>, as documented above.
- #
# == Accessing shared variables
#
# Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
@@ -176,7 +173,7 @@ module ActionController
super
return if (options.key?(:text) || options.key?(:inline) || options.key?(:partial)) && !options.key?(:layout)
- layout = options.key?(:layout) ? options[:layout] : :none
+ layout = options.key?(:layout) ? options[:layout] : :default
options[:_layout] = _layout_for_option(layout, options[:_template].details)
end
@@ -184,7 +181,7 @@ module ActionController
case name
when String then _layout_for_name(name, details)
when true then _default_layout(details, true)
- when :none then _default_layout(details, false)
+ when :default then _default_layout(details, false)
when false, nil then nil
else
raise ArgumentError,
diff --git a/actionpack/lib/action_controller/base/mime_responds.rb b/actionpack/lib/action_controller/base/mime_responds.rb
index 5c7218691e..ed0d58dba1 100644
--- a/actionpack/lib/action_controller/base/mime_responds.rb
+++ b/actionpack/lib/action_controller/base/mime_responds.rb
@@ -120,12 +120,9 @@ module ActionController #:nodoc:
@responses[mime_type] ||= Proc.new do
# TODO: Remove this when new base is merged in
- if defined?(Http)
- @controller.formats = [mime_type.to_sym]
- end
-
+ @controller.formats = [mime_type.to_sym]
+ @controller.content_type = mime_type
@controller.template.formats = [mime_type.to_sym]
- @response.content_type = mime_type
block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
end
diff --git a/actionpack/lib/action_controller/base/request_forgery_protection.rb b/actionpack/lib/action_controller/base/request_forgery_protection.rb
index a470c8eec1..6ba86cd0be 100644
--- a/actionpack/lib/action_controller/base/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/base/request_forgery_protection.rb
@@ -6,20 +6,16 @@ module ActionController #:nodoc:
extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include AbstractController::Helpers, Session
- end
+ include AbstractController::Helpers, Session
included do
- if defined?(ActionController::Http)
- # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
- # sets it to <tt>:authenticity_token</tt> by default.
- cattr_accessor :request_forgery_protection_token
+ # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
+ # sets it to <tt>:authenticity_token</tt> by default.
+ cattr_accessor :request_forgery_protection_token
- # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
- class_inheritable_accessor :allow_forgery_protection
- self.allow_forgery_protection = true
- end
+ # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
+ class_inheritable_accessor :allow_forgery_protection
+ self.allow_forgery_protection = true
helper_method :form_authenticity_token
helper_method :protect_against_forgery?
diff --git a/actionpack/lib/action_controller/base/streaming.rb b/actionpack/lib/action_controller/base/streaming.rb
index 5c72fc9ad9..70a97ccfec 100644
--- a/actionpack/lib/action_controller/base/streaming.rb
+++ b/actionpack/lib/action_controller/base/streaming.rb
@@ -4,10 +4,7 @@ module ActionController #:nodoc:
module Streaming
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include ActionController::Renderer
- end
+ include ActionController::Renderer
DEFAULT_SEND_FILE_OPTIONS = {
:type => 'application/octet-stream'.freeze,
diff --git a/actionpack/lib/action_controller/base/verification.rb b/actionpack/lib/action_controller/base/verification.rb
index d87b348ed4..951ae1bee1 100644
--- a/actionpack/lib/action_controller/base/verification.rb
+++ b/actionpack/lib/action_controller/base/verification.rb
@@ -2,10 +2,7 @@ module ActionController #:nodoc:
module Verification #:nodoc:
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include AbstractController::Callbacks, Session, Flash, Renderer
- end
+ include AbstractController::Callbacks, Session, Flash, Renderer
# This module provides a class-level method for specifying that certain
# actions are guarded against being called without certain prerequisites
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 54148b55d8..d8a1662acc 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -62,14 +62,7 @@ module ActionController #:nodoc:
cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options)
- # TODO: Remove this once new base is swapped in.
- if defined?(ActionController::Http)
- around_filter cache_filter, filter_options
- else
- around_filter(filter_options) do |controller, action|
- cache_filter.filter(controller, action)
- end
- end
+ around_filter cache_filter, filter_options
end
end
@@ -91,19 +84,10 @@ module ActionController #:nodoc:
@options = options
end
- # TODO: Remove once New Base is merged
- if defined?(ActionController::Http)
- def filter(controller)
- should_continue = before(controller)
- yield if should_continue
- after(controller)
- end
- else
- def filter(controller, action)
- should_continue = before(controller)
- action.call if should_continue
- after(controller)
- end
+ def filter(controller)
+ should_continue = before(controller)
+ yield if should_continue
+ after(controller)
end
def before(controller)
diff --git a/actionpack/lib/action_controller/legacy/layout.rb b/actionpack/lib/action_controller/legacy/layout.rb
index 3046e082d9..3f3d20b95f 100644
--- a/actionpack/lib/action_controller/legacy/layout.rb
+++ b/actionpack/lib/action_controller/legacy/layout.rb
@@ -44,9 +44,6 @@ module ActionController #:nodoc:
# hello world
# // The footer part of this layout
#
- # NOTE: The old notation for rendering the view from a layout was to expose the magic <tt>@content_for_layout</tt> instance
- # variable. The preferred notation now is to use <tt>yield</tt>, as documented above.
- #
# == Accessing shared variables
#
# Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
diff --git a/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb b/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
index d9b614c237..c6f7de17bd 100644
--- a/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
+++ b/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
@@ -112,8 +112,7 @@ module ActionController
# Returns the path component of a URL for the given record. It uses
# <tt>polymorphic_url</tt> with <tt>:routing_type => :path</tt>.
def polymorphic_path(record_or_hash_or_array, options = {})
- options[:routing_type] = :path
- polymorphic_url(record_or_hash_or_array, options)
+ polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
end
%w(edit new).each do |action|
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 25156a4c75..27f27e27fe 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -2,7 +2,19 @@ require 'set'
require 'active_support/core_ext/class/attribute_accessors'
module Mime
- SET = []
+ class Mimes < Array
+ def symbols
+ @symbols ||= map {|m| m.to_sym }
+ end
+
+ %w(<< concat shift unshift push pop []= clear compact! collect!
+ delete delete_at delete_if flatten! map! insert reject! reverse!
+ replace slice! sort! uniq!).each do |method|
+ define_method(method) {|*args| @symbols = nil; super(*args) }
+ end
+ end
+
+ SET = Mimes.new
EXTENSION_LOOKUP = {}
LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 140feb9a68..3f23a5af7a 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -180,12 +180,10 @@ module ActionDispatch
else
accepts.dup
end.tap do |ret|
- if defined?(ActionController::Http)
- if ret == ONLY_ALL
- ret.replace Mime::SET
- elsif all = ret.index(Mime::ALL)
- ret.delete_at(all) && ret.insert(all, *Mime::SET)
- end
+ if ret == ONLY_ALL
+ ret.replace Mime::SET
+ elsif all = ret.index(Mime::ALL)
+ ret.delete_at(all) && ret.insert(all, *Mime::SET)
end
end
else
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 94138097e3..27a06db5bb 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -33,21 +33,22 @@ module ActionView
[Base, InlineTemplate, TemplateError]
end
- autoload :Base, 'action_view/base'
- autoload :Helpers, 'action_view/helpers'
- autoload :InlineTemplate, 'action_view/template/inline'
- autoload :Partials, 'action_view/render/partials'
- autoload :Path, 'action_view/template/path'
- autoload :PathSet, 'action_view/paths'
- autoload :Rendering, 'action_view/render/rendering'
- autoload :Renderable, 'action_view/template/renderable'
+ autoload :Base, 'action_view/base'
+ autoload :Helpers, 'action_view/helpers'
+ autoload :InlineTemplate, 'action_view/template/inline'
+ autoload :Partials, 'action_view/render/partials'
+ autoload :Resolver, 'action_view/template/resolver'
+ autoload :PathSet, 'action_view/paths'
+ autoload :Rendering, 'action_view/render/rendering'
+ autoload :Renderable, 'action_view/template/renderable'
autoload :RenderablePartial, 'action_view/template/partial'
- autoload :Template, 'action_view/template/template'
- autoload :TemplateError, 'action_view/template/error'
- autoload :TemplateHandler, 'action_view/template/handler'
- autoload :TemplateHandlers, 'action_view/template/handlers'
- autoload :TextTemplate, 'action_view/template/text'
- autoload :Helpers, 'action_view/helpers'
+ autoload :Template, 'action_view/template/template'
+ autoload :TemplateError, 'action_view/template/error'
+ autoload :TemplateHandler, 'action_view/template/handler'
+ autoload :TemplateHandlers, 'action_view/template/handlers'
+ autoload :TextTemplate, 'action_view/template/text'
+ autoload :Helpers, 'action_view/helpers'
+ autoload :FileSystemResolverWithFallback, 'action_view/template/resolver'
end
class ERB
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 4ab568b44c..45184f58fb 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -170,12 +170,13 @@ module ActionView #:nodoc:
attr_accessor :base_path, :assigns, :template_extension, :formats
attr_accessor :controller
+ attr_internal :captures
attr_accessor :output_buffer
class << self
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
- delegate :logger, :to => 'ActionController::Base'
+ delegate :logger, :to => 'ActionController::Base', :allow_nil => true
end
@@debug_rjs = false
@@ -229,38 +230,27 @@ module ActionView #:nodoc:
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc:
@formats = formats || [:html]
- @assigns = assigns_for_first_render
- @assigns_added = nil
+ @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
@controller = controller
@helpers = ProxyModule.new(self)
+ @_content_for = Hash.new {|h,k| h[k] = "" }
self.view_paths = view_paths
-
- @_first_render = nil
- @_current_render = nil
end
+ attr_internal :template
attr_reader :view_paths
def view_paths=(paths)
@view_paths = self.class.process_view_paths(paths)
end
- # Access the current template being rendered.
- # Returns a ActionView::Template object.
- def template
- @_current_render
- end
-
- def template=(template) #:nodoc:
- @_first_render ||= template
- @_current_render = template
- end
-
def with_template(current_template)
+ _evaluate_assigns_and_ivars
last_template, self.template = template, current_template
+ last_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols
yield
ensure
- self.template = last_template
+ self.template, self.formats = last_template, last_formats
end
def punctuate_body!(part)
@@ -271,30 +261,19 @@ module ActionView #:nodoc:
# Evaluates the local assigns and controller ivars, pushes them to the view.
def _evaluate_assigns_and_ivars #:nodoc:
- unless @assigns_added
- @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
- _copy_ivars_from_controller
- @assigns_added = true
- end
+ @assigns_added ||= _copy_ivars_from_controller
end
- private
+ private
- def _copy_ivars_from_controller #:nodoc:
- if @controller
- variables = @controller.instance_variable_names
- variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
- variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
- end
+ def _copy_ivars_from_controller #:nodoc:
+ if @controller
+ variables = @controller.instance_variable_names
+ variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
+ variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
end
+ true
+ end
- def _set_controller_content_type(content_type) #:nodoc:
- # TODO: Remove this method when new base is switched
- unless defined?(ActionController::Http)
- if controller.respond_to?(:response)
- controller.response.content_type ||= content_type
- end
- end
- end
end
end
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb
index 8b70200654..75cc651968 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -122,9 +122,9 @@ module ActionView
options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
- (errors = obj.errors.on(method))
+ (errors = obj.errors[method])
content_tag("div",
- "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.is_a?(Array) ? errors.first : errors)}#{options[:append_text]}",
+ "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}",
:class => options[:css_class]
)
else
@@ -247,59 +247,22 @@ module ActionView
end
end
- alias_method :tag_without_error_wrapping, :tag
- def tag(name, options)
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
- else
- tag_without_error_wrapping(name, options)
- end
- end
-
- alias_method :content_tag_without_error_wrapping, :content_tag
- def content_tag(name, value, options)
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name))
- else
- content_tag_without_error_wrapping(name, value, options)
- end
- end
-
- alias_method :to_date_select_tag_without_error_wrapping, :to_date_select_tag
- def to_date_select_tag(options = {}, html_options = {})
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(to_date_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
- else
- to_date_select_tag_without_error_wrapping(options, html_options)
- end
- end
-
- alias_method :to_datetime_select_tag_without_error_wrapping, :to_datetime_select_tag
- def to_datetime_select_tag(options = {}, html_options = {})
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(to_datetime_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
- else
- to_datetime_select_tag_without_error_wrapping(options, html_options)
+ %w(tag content_tag to_date_select_tag to_datetime_select_tag to_time_select_tag).each do |meth|
+ without = "#{meth}_without_error_wrapping"
+ define_method "#{meth}_with_error_wrapping" do |*args|
+ error_wrapping(send(without, *args))
end
+ alias_method_chain meth, :error_wrapping
end
- alias_method :to_time_select_tag_without_error_wrapping, :to_time_select_tag
- def to_time_select_tag(options = {}, html_options = {})
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(to_time_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
+ def error_wrapping(html_tag)
+ if object.respond_to?(:errors) && object.errors.respond_to?(:full_messages) && object.errors[@method_name].any?
+ Base.field_error_proc.call(html_tag, self)
else
- to_time_select_tag_without_error_wrapping(options, html_options)
+ html_tag
end
end
- def error_wrapping(html_tag, has_error)
- has_error ? Base.field_error_proc.call(html_tag, self) : html_tag
- end
-
- def error_message
- object.errors.on(@method_name)
- end
-
def column_type
object.send(:column_for_attribute, @method_name).type
end
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index b4197479a0..c90acc5ac2 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -111,15 +111,32 @@ module ActionView
#
# WARNING: content_for is ignored in caches. So you shouldn't use it
# for elements that will be fragment cached.
- #
- # The deprecated way of accessing a content_for block is to use an instance variable
- # named <tt>@content_for_#{name_of_the_content_block}</tt>. The preferred usage is now
- # <tt><%= yield :footer %></tt>.
def content_for(name, content = nil, &block)
- ivar = "@content_for_#{name}"
content = capture(&block) if block_given?
- instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
- nil
+ return @_content_for[name] << content if content
+ @_content_for[name]
+ end
+
+ # content_for? simply checks whether any content has been captured yet using content_for
+ # Useful to render parts of your layout differently based on what is in your views.
+ #
+ # ==== Examples
+ #
+ # Perhaps you will use different css in you layout if no content_for :right_column
+ #
+ # <%# This is the layout %>
+ # <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ # <head>
+ # <title>My Website</title>
+ # <%= yield :script %>
+ # </head>
+ # <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
+ # <%= yield %>
+ # <%= yield :right_col %>
+ # </body>
+ # </html>
+ def content_for?(name)
+ @_content_for[name].present?
end
# Use an alternate output buffer for the duration of the block.
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index 95c56faf9c..074b475819 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -3,7 +3,7 @@ module ActionView #:nodoc:
def self.type_cast(obj)
if obj.is_a?(String)
cache = !defined?(Rails) || !Rails.respond_to?(:configuration) || Rails.configuration.cache_classes
- Template::FileSystemPathWithFallback.new(obj, :cache => cache)
+ FileSystemResolverWithFallback.new(obj, :cache => cache)
else
obj
end
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index eacf117bea..87314fff67 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -245,13 +245,6 @@ module ActionView
end
end
- def _render_partial_with_block(layout, block, options)
- @_proc_for_layout = block
- concat(_render_partial(options.merge(:partial => layout)))
- ensure
- @_proc_for_layout = nil
- end
-
def _render_partial_with_layout(layout, options)
if layout
prefix = controller && !layout.include?("/") ? controller.controller_path : nil
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index fe785e7b20..162e38c484 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -51,32 +51,60 @@ module ActionView
end
begin
- original_content_for_layout = @content_for_layout if defined?(@content_for_layout)
- @content_for_layout = content
+ old_content, @_content_for[:layout] = @_content_for[:layout], content
- @cached_content_for_layout = @content_for_layout
+ @cached_content_for_layout = @_content_for[:layout]
_render_template(layout, locals)
ensure
- @content_for_layout = original_content_for_layout
+ @_content_for[:layout] = old_content
end
end
+ # You can think of a layout as a method that is called with a block. This method
+ # returns the block that the layout is called with. If the user calls yield :some_name,
+ # the block, by default, returns content_for(:some_name). If the user calls yield,
+ # the default block returns content_for(:layout).
+ #
+ # The user can override this default by passing a block to the layout.
+ #
+ # ==== Example
+ #
+ # # The template
+ # <% render :layout => "my_layout" do %>Content<% end %>
+ #
+ # # The layout
+ # <html><% yield %></html>
+ #
+ # In this case, instead of the default block, which would return content_for(:layout),
+ # this method returns the block that was passed in to render layout, and the response
+ # would be <html>Content</html>.
+ #
+ # Finally, the block can take block arguments, which can be passed in by yield.
+ #
+ # ==== Example
+ #
+ # # The template
+ # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %>
+ #
+ # # The layout
+ # <html><% yield Struct.new(:name).new("David") %></html>
+ #
+ # In this case, the layout would receive the block passed into <tt>render :layout</tt>,
+ # and the Struct specified in the layout would be passed into the block. The result
+ # would be <html>Hello David</html>.
+ def layout_proc(name)
+ @_default_layout ||= proc { |*names| @_content_for[names.first || :layout] }
+ !@_content_for.key?(name) && @_proc_for_layout || @_default_layout
+ end
+
def _render_template(template, local_assigns = {})
with_template(template) do
- _evaluate_assigns_and_ivars
- _set_controller_content_type(template.mime_type) if template.respond_to?(:mime_type)
-
template.render(self, local_assigns) do |*names|
- if !instance_variable_defined?(:"@content_for_#{names.first}") &&
- instance_variable_defined?(:@_proc_for_layout) && (proc = @_proc_for_layout)
- capture(*names, &proc)
- elsif instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
- instance_variable_get(ivar)
- end
+ capture(*names, &layout_proc(names.first))
end
end
rescue Exception => e
- if TemplateError === e
+ if e.is_a?(TemplateError)
e.sub_template_of(template)
raise e
else
@@ -101,20 +129,18 @@ module ActionView
end
def _render_template_with_layout(template, layout = nil, options = {}, partial = false)
- if controller && logger
- logger.info("Rendering #{template.identifier}" +
- (options[:status] ? " (#{options[:status]})" : ''))
- end
-
+ logger && logger.info("Rendering #{template.identifier}#{' (#{options[:status]})' if options[:status]}")
+
+ locals = options[:locals] || {}
+
content = if partial
object = partial unless partial == true
_render_partial_object(template, options, object)
else
- _render_template(template, options[:locals] || {})
+ _render_template(template, locals)
end
- return content unless layout
- _render_content_with_layout(content, layout, options[:locals] || {})
+ layout ? _render_content_with_layout(content, layout, locals) : content
end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb
index f412228752..abe140af0b 100644
--- a/actionpack/lib/action_view/template/handlers/builder.rb
+++ b/actionpack/lib/action_view/template/handlers/builder.rb
@@ -8,8 +8,7 @@ module ActionView
self.default_format = Mime::XML
def compile(template)
- "_set_controller_content_type(Mime::XML);" +
- "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
+ "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
";xml.target!;"
diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb
index a36744c2b7..b1d15dc209 100644
--- a/actionpack/lib/action_view/template/handlers/rjs.rb
+++ b/actionpack/lib/action_view/template/handlers/rjs.rb
@@ -6,7 +6,6 @@ module ActionView
self.default_format = Mime::JS
def compile(template)
- "@formats = [:html];" +
"controller.response.content_type ||= Mime::JS;" +
"update_page do |page|;#{template.source}\nend"
end
diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb
deleted file mode 100644
index 478bf96c9a..0000000000
--- a/actionpack/lib/action_view/template/path.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-require "pathname"
-
-module ActionView
- class Template
- # Abstract super class
- class Path
- def initialize(options)
- @cache = options[:cache]
- @cached = {}
- end
-
- # Normalizes the arguments and passes it on to find_template
- def find_by_parts(*args)
- find_all_by_parts(*args).first
- end
-
- def find_all_by_parts(name, details = {}, prefix = nil, partial = nil)
- details[:locales] = [I18n.locale]
- name = name.to_s.gsub(handler_matcher, '').split("/")
- find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial)
- end
-
- private
-
- # This is what child classes implement. No defaults are needed
- # because Path guarentees that the arguments are present and
- # normalized.
- def find_templates(name, details, prefix, partial)
- raise NotImplementedError
- end
-
- def valid_handlers
- @valid_handlers ||= TemplateHandlers.extensions
- end
-
- def handler_matcher
- @handler_matcher ||= begin
- e = valid_handlers.join('|')
- /\.(?:#{e})$/
- end
- end
-
- def handler_glob
- e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join
- "{#{e}}"
- end
-
- def formats_glob
- @formats_glob ||= begin
- formats = Mime::SET.map { |m| m.symbol }
- '{' + formats.map { |l| ".#{l}," }.join + '}'
- end
- end
-
- def cached(key)
- return yield unless @cache
- return @cached[key] if @cached.key?(key)
- @cached[key] = yield
- end
- end
-
- class FileSystemPath < Path
-
- def initialize(path, options = {})
- raise ArgumentError, "path already is a Path class" if path.is_a?(Path)
- super(options)
- @path = Pathname.new(path).expand_path
- end
-
- # TODO: This is the currently needed API. Make this suck less
- # ==== <suck>
- attr_reader :path
-
- def to_s
- path.to_s
- end
-
- def to_str
- path.to_s
- end
-
- def ==(path)
- to_str == path.to_str
- end
-
- def eql?(path)
- to_str == path.to_str
- end
- # ==== </suck>
-
- def find_templates(name, details, prefix, partial, root = "#{@path}/")
- if glob = details_to_glob(name, details, prefix, partial, root)
- cached(glob) do
- Dir[glob].map do |path|
- next if File.directory?(path)
- source = File.read(path)
- identifier = Pathname.new(path).expand_path.to_s
-
- Template.new(source, identifier, *path_to_details(path))
- end.compact
- end
- end
- end
-
- private
-
- # :api: plugin
- def details_to_glob(name, details, prefix, partial, root)
- path = ""
- path << "#{prefix}/" unless prefix.empty?
- path << (partial ? "_#{name}" : name)
-
- extensions = ""
- [:locales, :formats].each do |k|
- extensions << if exts = details[k]
- '{' + exts.map {|e| ".#{e},"}.join + '}'
- else
- k == :formats ? formats_glob : ''
- end
- end
-
- "#{root}#{path}#{extensions}#{handler_glob}"
- end
-
- # TODO: fix me
- # :api: plugin
- def path_to_details(path)
- # [:erb, :format => :html, :locale => :en, :partial => true/false]
- if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$')
- partial = m[1] == '_'
- details = (m[2]||"").split('.').reject { |e| e.empty? }
- handler = Template.handler_class_for_extension(m[3])
-
- format = Mime[details.last] && details.pop.to_sym
- locale = details.last && details.pop.to_sym
-
- return handler, :format => format, :locale => locale, :partial => partial
- end
- end
- end
-
- class FileSystemPathWithFallback < FileSystemPath
-
- def find_templates(name, details, prefix, partial)
- templates = super
- return super(name, details, prefix, partial, '') if templates.empty?
- templates
- end
-
- end
- end
-end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
new file mode 100644
index 0000000000..d15f53a11b
--- /dev/null
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -0,0 +1,150 @@
+require "pathname"
+require "action_view/template/template"
+
+module ActionView
+ # Abstract superclass
+ class Resolver
+ def initialize(options)
+ @cache = options[:cache]
+ @cached = {}
+ end
+
+ # Normalizes the arguments and passes it on to find_template
+ def find_by_parts(*args)
+ find_all_by_parts(*args).first
+ end
+
+ def find_all_by_parts(name, details = {}, prefix = nil, partial = nil)
+ details[:locales] = [I18n.locale]
+ name = name.to_s.gsub(handler_matcher, '').split("/")
+ find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial)
+ end
+
+ private
+
+ # This is what child classes implement. No defaults are needed
+ # because Resolver guarantees that the arguments are present and
+ # normalized.
+ def find_templates(name, details, prefix, partial)
+ raise NotImplementedError
+ end
+
+ def valid_handlers
+ @valid_handlers ||= TemplateHandlers.extensions
+ end
+
+ def handler_matcher
+ @handler_matcher ||= begin
+ e = valid_handlers.join('|')
+ /\.(?:#{e})$/
+ end
+ end
+
+ def handler_glob
+ e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join
+ "{#{e}}"
+ end
+
+ def formats_glob
+ @formats_glob ||= begin
+ '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}'
+ end
+ end
+
+ def cached(key)
+ return yield unless @cache
+ return @cached[key] if @cached.key?(key)
+ @cached[key] = yield
+ end
+ end
+
+ class FileSystemResolver < Resolver
+
+ def initialize(path, options = {})
+ raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
+ super(options)
+ @path = Pathname.new(path).expand_path
+ end
+
+ # TODO: This is the currently needed API. Make this suck less
+ # ==== <suck>
+ attr_reader :path
+
+ def to_s
+ path.to_s
+ end
+
+ def to_str
+ path.to_s
+ end
+
+ def ==(path)
+ to_str == path.to_str
+ end
+
+ def eql?(path)
+ to_str == path.to_str
+ end
+ # ==== </suck>
+
+ def find_templates(name, details, prefix, partial, root = "#{@path}/")
+ if glob = details_to_glob(name, details, prefix, partial, root)
+ cached(glob) do
+ Dir[glob].map do |path|
+ next if File.directory?(path)
+ source = File.read(path)
+ identifier = Pathname.new(path).expand_path.to_s
+
+ Template.new(source, identifier, *path_to_details(path))
+ end.compact
+ end
+ end
+ end
+
+ private
+
+ # :api: plugin
+ def details_to_glob(name, details, prefix, partial, root)
+ path = ""
+ path << "#{prefix}/" unless prefix.empty?
+ path << (partial ? "_#{name}" : name)
+
+ extensions = ""
+ [:locales, :formats].each do |k|
+ extensions << if exts = details[k]
+ '{' + exts.map {|e| ".#{e},"}.join + '}'
+ else
+ k == :formats ? formats_glob : ''
+ end
+ end
+
+ "#{root}#{path}#{extensions}#{handler_glob}"
+ end
+
+ # TODO: fix me
+ # :api: plugin
+ def path_to_details(path)
+ # [:erb, :format => :html, :locale => :en, :partial => true/false]
+ if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$')
+ partial = m[1] == '_'
+ details = (m[2]||"").split('.').reject { |e| e.empty? }
+ handler = Template.handler_class_for_extension(m[3])
+
+ format = Mime[details.last] && details.pop.to_sym
+ locale = details.last && details.pop.to_sym
+
+ return handler, :format => format, :locale => locale, :partial => partial
+ end
+ end
+ end
+
+ class FileSystemResolverWithFallback < FileSystemResolver
+
+ def find_templates(name, details, prefix, partial)
+ templates = super
+ return super(name, details, prefix, partial, '') if templates.empty?
+ templates
+ end
+
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb
index e7ea42c2eb..fac50cd692 100644
--- a/actionpack/lib/action_view/template/template.rb
+++ b/actionpack/lib/action_view/template/template.rb
@@ -2,7 +2,7 @@
# This is so that templates compiled in this file are UTF-8
require 'set'
-require "action_view/template/path"
+require "action_view/template/resolver"
module ActionView
class Template
@@ -20,7 +20,7 @@ module ActionView
handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html"
end
@mime_type = Mime::Type.lookup_by_extension(format.to_s)
- @details[:formats] = Array.wrap(format && format.to_sym)
+ @details[:formats] = Array.wrap(format.to_sym)
end
def render(view, locals, &blk)
diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb
index fd57b1677e..81944ff546 100644
--- a/actionpack/lib/action_view/template/text.rb
+++ b/actionpack/lib/action_view/template/text.rb
@@ -3,7 +3,7 @@ module ActionView #:nodoc:
def initialize(string, content_type = Mime[:html])
super(string.to_s)
- @content_type = Mime[content_type]
+ @content_type = Mime[content_type] || content_type
end
def details