UtopiaSourceUtopiaControllerRespond

module Respond

A controller layer which provides a convenient way to respond to different requested content types. The order in which you add converters matters, as it determines how the incoming Accept: header is mapped, e.g. the first converter is also defined as matching the media range /.

Nested

Definitions

def self.prepended(base)

Extend a controller class with response negotiation.

Signature

parameter base Class

The controller class.

returns Class

The extended controller class.

Implementation

def self.prepended(base)
	base.extend(ClassMethods)
end

def respond_to(request)

Bind this controller's responder to the request.

Signature

parameter request Rack::Request

The request.

returns Responder::Responds | Nil

The bound responder, if one has been configured.

Implementation

def respond_to(request)
	self.class.respond_to(self, request)
end

def response_for(request, original_response)

Build a response for the negotiated content type.

Signature

parameter request Rack::Request

The request.

parameter original_response Object

The original response.

returns Array

The response.

Implementation

def response_for(request, original_response)
	response = catch(:response) do
		self.class.response_for(self, request, original_response)
		
		# If the above code did not throw a new response, we return the original:
		return original_response
	end
	
	# If the user called {Base#ignore!}, it's possible response is nil:
	if response
		# There was an updated response so merge it:
		return [original_response[0], original_response[1].merge(response[1]), response[2] || original_response[2]]
	end
end

def process!(request, path)

Invokes super. If a response is generated, format it based on the Accept: header, unless the content type was already specified.

Implementation

def process!(request, path)
	if response = super
		headers = response[1]
		
		# Don't try to convert the response if a content type was explicitly specified.
		if headers[HTTP::CONTENT_TYPE]
			return response
		else
			return self.response_for(request, response)
		end
	end
end