mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Added responds_to to new base.
This commit is contained in:
parent
c03b0ca7eb
commit
01f032f256
11 changed files with 148 additions and 125 deletions
|
@ -66,7 +66,12 @@ module AbstractController
|
|||
raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
|
||||
end
|
||||
|
||||
name && view_paths.find_by_parts(name, {:formats => formats}, "layouts")
|
||||
name && view_paths.find_by_parts(name, {:formats => formats}, _layout_prefix(name))
|
||||
end
|
||||
|
||||
# TODO: Decide if this is the best hook point for the feature
|
||||
def _layout_prefix(name)
|
||||
"layouts"
|
||||
end
|
||||
|
||||
def _default_layout(require_layout = false)
|
||||
|
|
|
@ -1,111 +1,103 @@
|
|||
module ActionController #:nodoc:
|
||||
module MimeResponds #:nodoc:
|
||||
def self.included(base)
|
||||
base.module_eval do
|
||||
include ActionController::MimeResponds::InstanceMethods
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
# Without web-service support, an action which collects the data for displaying a list of people
|
||||
# might look something like this:
|
||||
#
|
||||
# def index
|
||||
# @people = Person.find(:all)
|
||||
# end
|
||||
#
|
||||
# Here's the same action, with web-service support baked in:
|
||||
#
|
||||
# def index
|
||||
# @people = Person.find(:all)
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html
|
||||
# format.xml { render :xml => @people.to_xml }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# What that says is, "if the client wants HTML in response to this action, just respond as we
|
||||
# would have before, but if the client wants XML, return them the list of people in XML format."
|
||||
# (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
|
||||
#
|
||||
# Supposing you have an action that adds a new person, optionally creating their company
|
||||
# (by name) if it does not already exist, without web-services, it might look like this:
|
||||
#
|
||||
# def create
|
||||
# @company = Company.find_or_create_by_name(params[:company][:name])
|
||||
# @person = @company.people.create(params[:person])
|
||||
#
|
||||
# redirect_to(person_list_url)
|
||||
# end
|
||||
#
|
||||
# Here's the same action, with web-service support baked in:
|
||||
#
|
||||
# def create
|
||||
# company = params[:person].delete(:company)
|
||||
# @company = Company.find_or_create_by_name(company[:name])
|
||||
# @person = @company.people.create(params[:person])
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html { redirect_to(person_list_url) }
|
||||
# format.js
|
||||
# format.xml { render :xml => @person.to_xml(:include => @company) }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# If the client wants HTML, we just redirect them back to the person list. If they want Javascript
|
||||
# (format.js), then it is an RJS request and we render the RJS template associated with this action.
|
||||
# Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also
|
||||
# include the person's company in the rendered XML, so you get something like this:
|
||||
#
|
||||
# <person>
|
||||
# <id>...</id>
|
||||
# ...
|
||||
# <company>
|
||||
# <id>...</id>
|
||||
# <name>...</name>
|
||||
# ...
|
||||
# </company>
|
||||
# </person>
|
||||
#
|
||||
# Note, however, the extra bit at the top of that action:
|
||||
#
|
||||
# company = params[:person].delete(:company)
|
||||
# @company = Company.find_or_create_by_name(company[:name])
|
||||
#
|
||||
# This is because the incoming XML document (if a web-service request is in process) can only contain a
|
||||
# single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):
|
||||
#
|
||||
# person[name]=...&person[company][name]=...&...
|
||||
#
|
||||
# And, like this (xml-encoded):
|
||||
#
|
||||
# <person>
|
||||
# <name>...</name>
|
||||
# <company>
|
||||
# <name>...</name>
|
||||
# </company>
|
||||
# </person>
|
||||
#
|
||||
# In other words, we make the request so that it operates on a single entity's person. Then, in the action,
|
||||
# we extract the company data from the request, find or create the company, and then create the new person
|
||||
# with the remaining data.
|
||||
#
|
||||
# Note that you can define your own XML parameter parser which would allow you to describe multiple entities
|
||||
# in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow
|
||||
# and accept Rails' defaults, life will be much easier.
|
||||
#
|
||||
# If you need to use a MIME type which isn't supported by default, you can register your own handlers in
|
||||
# environment.rb as follows.
|
||||
#
|
||||
# Mime::Type.register "image/jpg", :jpg
|
||||
def respond_to(*types, &block)
|
||||
raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
|
||||
block ||= lambda { |responder| types.each { |type| responder.send(type) } }
|
||||
responder = Responder.new(self)
|
||||
block.call(responder)
|
||||
responder.respond
|
||||
end
|
||||
# Without web-service support, an action which collects the data for displaying a list of people
|
||||
# might look something like this:
|
||||
#
|
||||
# def index
|
||||
# @people = Person.find(:all)
|
||||
# end
|
||||
#
|
||||
# Here's the same action, with web-service support baked in:
|
||||
#
|
||||
# def index
|
||||
# @people = Person.find(:all)
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html
|
||||
# format.xml { render :xml => @people.to_xml }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# What that says is, "if the client wants HTML in response to this action, just respond as we
|
||||
# would have before, but if the client wants XML, return them the list of people in XML format."
|
||||
# (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
|
||||
#
|
||||
# Supposing you have an action that adds a new person, optionally creating their company
|
||||
# (by name) if it does not already exist, without web-services, it might look like this:
|
||||
#
|
||||
# def create
|
||||
# @company = Company.find_or_create_by_name(params[:company][:name])
|
||||
# @person = @company.people.create(params[:person])
|
||||
#
|
||||
# redirect_to(person_list_url)
|
||||
# end
|
||||
#
|
||||
# Here's the same action, with web-service support baked in:
|
||||
#
|
||||
# def create
|
||||
# company = params[:person].delete(:company)
|
||||
# @company = Company.find_or_create_by_name(company[:name])
|
||||
# @person = @company.people.create(params[:person])
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html { redirect_to(person_list_url) }
|
||||
# format.js
|
||||
# format.xml { render :xml => @person.to_xml(:include => @company) }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# If the client wants HTML, we just redirect them back to the person list. If they want Javascript
|
||||
# (format.js), then it is an RJS request and we render the RJS template associated with this action.
|
||||
# Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also
|
||||
# include the person's company in the rendered XML, so you get something like this:
|
||||
#
|
||||
# <person>
|
||||
# <id>...</id>
|
||||
# ...
|
||||
# <company>
|
||||
# <id>...</id>
|
||||
# <name>...</name>
|
||||
# ...
|
||||
# </company>
|
||||
# </person>
|
||||
#
|
||||
# Note, however, the extra bit at the top of that action:
|
||||
#
|
||||
# company = params[:person].delete(:company)
|
||||
# @company = Company.find_or_create_by_name(company[:name])
|
||||
#
|
||||
# This is because the incoming XML document (if a web-service request is in process) can only contain a
|
||||
# single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):
|
||||
#
|
||||
# person[name]=...&person[company][name]=...&...
|
||||
#
|
||||
# And, like this (xml-encoded):
|
||||
#
|
||||
# <person>
|
||||
# <name>...</name>
|
||||
# <company>
|
||||
# <name>...</name>
|
||||
# </company>
|
||||
# </person>
|
||||
#
|
||||
# In other words, we make the request so that it operates on a single entity's person. Then, in the action,
|
||||
# we extract the company data from the request, find or create the company, and then create the new person
|
||||
# with the remaining data.
|
||||
#
|
||||
# Note that you can define your own XML parameter parser which would allow you to describe multiple entities
|
||||
# in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow
|
||||
# and accept Rails' defaults, life will be much easier.
|
||||
#
|
||||
# If you need to use a MIME type which isn't supported by default, you can register your own handlers in
|
||||
# environment.rb as follows.
|
||||
#
|
||||
# Mime::Type.register "image/jpg", :jpg
|
||||
def respond_to(*types, &block)
|
||||
raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
|
||||
block ||= lambda { |responder| types.each { |type| responder.send(type) } }
|
||||
responder = Responder.new(self)
|
||||
block.call(responder)
|
||||
responder.respond
|
||||
end
|
||||
|
||||
class Responder #:nodoc:
|
||||
|
@ -127,8 +119,15 @@ module ActionController #:nodoc:
|
|||
@order << mime_type
|
||||
|
||||
@responses[mime_type] ||= Proc.new do
|
||||
@controller.template.formats = [mime_type.to_sym]
|
||||
@response.content_type = mime_type.to_s
|
||||
# TODO: Remove this when new base is merged in
|
||||
if defined?(Http)
|
||||
@controller.formats = [mime_type.to_sym]
|
||||
@controller.template.formats = [mime_type.to_sym]
|
||||
else
|
||||
@controller.template.formats = [mime_type.to_sym]
|
||||
@response.content_type = mime_type.to_s
|
||||
end
|
||||
|
||||
block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ module ActionController
|
|||
# require 'action_controller/routing'
|
||||
autoload :Caching, 'action_controller/caching'
|
||||
autoload :Dispatcher, 'action_controller/dispatch/dispatcher'
|
||||
autoload :MimeResponds, 'action_controller/base/mime_responds'
|
||||
autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes'
|
||||
autoload :RecordIdentifier, 'action_controller/record_identifier'
|
||||
autoload :Resources, 'action_controller/routing/resources'
|
||||
|
|
|
@ -18,6 +18,7 @@ module ActionController
|
|||
include SessionManagement
|
||||
include ActionDispatch::StatusCodes
|
||||
include ActionController::Caching
|
||||
include ActionController::MimeResponds
|
||||
|
||||
# Rails 2.x compatibility
|
||||
include ActionController::Rails2Compatibility
|
||||
|
|
|
@ -59,6 +59,11 @@ module ActionController
|
|||
def initialize_template_class(*) end
|
||||
def assign_shortcuts(*) end
|
||||
|
||||
# TODO: Remove this after we flip
|
||||
def template
|
||||
_action_view
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def protect_from_forgery() end
|
||||
def consider_all_requests_local() end
|
||||
|
@ -95,10 +100,8 @@ module ActionController
|
|||
super || (respond_to?(:method_missing) && "_handle_method_missing")
|
||||
end
|
||||
|
||||
def _layout_for_name(name)
|
||||
name &&= name.sub(%r{^/?layouts/}, '')
|
||||
super
|
||||
def _layout_prefix(name)
|
||||
super unless name =~ /\blayouts/
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -18,7 +18,7 @@ module ActionController
|
|||
_process_options(options)
|
||||
|
||||
if options.key?(:text)
|
||||
options[:_template] = ActionView::TextTemplate.new(_text(options))
|
||||
options[:_template] = ActionView::TextTemplate.new(_text(options), formats.first)
|
||||
template = nil
|
||||
elsif options.key?(:inline)
|
||||
handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
|
||||
|
|
|
@ -7,7 +7,7 @@ module ActionController
|
|||
@_response = response
|
||||
@_response.request = request
|
||||
ret = process(request.parameters[:action])
|
||||
@_response.body = self.response_body || " "
|
||||
@_response.body ||= self.response_body || " "
|
||||
@_response.prepare!
|
||||
set_test_assigns
|
||||
ret
|
||||
|
|
|
@ -41,6 +41,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
def recycle!
|
||||
@formats = nil
|
||||
@env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
|
||||
@env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
|
||||
@env['action_dispatch.request.query_parameters'] = {}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
module ActionView #:nodoc:
|
||||
class TextTemplate < String #:nodoc:
|
||||
|
||||
def initialize(string, content_type = Mime[:html])
|
||||
super(string)
|
||||
@content_type = Mime[content_type]
|
||||
end
|
||||
|
||||
def identifier() self end
|
||||
|
||||
def render(*) self end
|
||||
|
||||
def mime_type() Mime::HTML end
|
||||
def mime_type() @content_type end
|
||||
|
||||
def partial?() false end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,8 @@ class PageCachingTest < ActionController::TestCase
|
|||
super
|
||||
ActionController::Base.perform_caching = true
|
||||
|
||||
ActionController::Routing::Routes.clear!
|
||||
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.main '', :controller => 'posts'
|
||||
map.formatted_posts 'posts.:format', :controller => 'posts'
|
||||
|
|
|
@ -437,7 +437,7 @@ class MimeControllerTest < ActionController::TestCase
|
|||
@controller.instance_eval do
|
||||
def render(*args)
|
||||
unless args.empty?
|
||||
@action = args.first[:action]
|
||||
@action = args.first[:action] || action_name
|
||||
end
|
||||
response.body = "#{@action} - #{@template.formats}"
|
||||
end
|
||||
|
@ -490,14 +490,15 @@ class PostController < AbstractPostController
|
|||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def with_iphone
|
||||
Mime::Type.register_alias("text/html", :iphone)
|
||||
request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
|
||||
yield
|
||||
ensure
|
||||
Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
|
||||
end
|
||||
protected
|
||||
|
||||
def with_iphone
|
||||
Mime::Type.register_alias("text/html", :iphone)
|
||||
request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
|
||||
yield
|
||||
ensure
|
||||
Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
|
||||
end
|
||||
end
|
||||
|
||||
class SuperPostController < PostController
|
||||
|
@ -509,6 +510,11 @@ class SuperPostController < PostController
|
|||
end
|
||||
end
|
||||
|
||||
if ENV["new_base"]
|
||||
PostController._write_layout_method
|
||||
SuperPostController._write_layout_method
|
||||
end
|
||||
|
||||
class MimeControllerLayoutsTest < ActionController::TestCase
|
||||
tests PostController
|
||||
|
||||
|
|
Loading…
Reference in a new issue