Skip to content

Commit

Permalink
Simpler RenderOption API -- removes the need for registering the type…
Browse files Browse the repository at this point in the history
…s and extending a module
  • Loading branch information
Carlhuda committed Dec 9, 2009
1 parent 9fbde11 commit f9d570b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 56 deletions.
101 changes: 45 additions & 56 deletions actionpack/lib/action_controller/metal/render_options.rb
@@ -1,19 +1,24 @@
module ActionController module ActionController

def self.add_renderer(key, &block)
RenderOptions.add(key, &block)
end

module RenderOptions module RenderOptions
extend ActiveSupport::Concern extend ActiveSupport::Concern


included do included do
extlib_inheritable_accessor :_renderers extlib_inheritable_accessor :_renderers
self._renderers = [] self._renderers = {}
end end


module ClassMethods module ClassMethods
def _write_render_options def _write_render_options
renderers = _renderers.map do |r| renderers = _renderers.map do |name, value|
<<-RUBY_EVAL <<-RUBY_EVAL
if options.key?(:#{r}) if options.key?(:#{name})
_process_options(options) _process_options(options)
return render_#{r}(options[:#{r}], options) return _render_option_#{name}(options[:#{name}], options)
end end
RUBY_EVAL RUBY_EVAL
end end
Expand All @@ -25,79 +30,63 @@ def _handle_render_options(options)
RUBY_EVAL RUBY_EVAL
end end


def _add_render_option(name) def use_renderers(*args)
_renderers << name args.each do |key|
_renderers[key] = RENDERERS[key]
end
_write_render_options _write_render_options
end end
alias use_renderer use_renderers
end end


def render_to_body(options) def render_to_body(options)
_handle_render_options(options) || super _handle_render_options(options) || super
end end
end

module RenderOption #:nodoc:
def self.extended(base)
base.extend ActiveSupport::Concern
base.send :include, ::ActionController::RenderOptions


def base.register_renderer(name) RENDERERS = {}
included { _add_render_option(name) } def self.add(key, &block)
end define_method("_render_option_#{key}", &block)
RENDERERS[key] = block
All._write_render_options
end end
end


module RenderOptions module All
module Json extend ActiveSupport::Concern
extend RenderOption include RenderOptions
register_renderer :json


def render_json(json, options) INCLUDED = []
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str) included do
json = "#{options[:callback]}(#{json})" unless options[:callback].blank? self._renderers = RENDERERS
self.content_type ||= Mime::JSON _write_render_options
self.response_body = json INCLUDED << self
end end
end

module Js
extend RenderOption
register_renderer :js


def render_js(js, options) def self._write_render_options
self.content_type ||= Mime::JS INCLUDED.each(&:_write_render_options)
self.response_body = js.respond_to?(:to_js) ? js.to_js : js
end end
end end


module Xml add :json do |json, options|
extend RenderOption json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
register_renderer :xml json = "#{options[:callback]}(#{json})" unless options[:callback].blank?

self.content_type ||= Mime::JSON
def render_xml(xml, options) self.response_body = json
self.content_type ||= Mime::XML
self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
end
end end


module RJS add :js do |js, options|
extend RenderOption self.content_type ||= Mime::JS
register_renderer :update self.response_body = js.respond_to?(:to_js) ? js.to_js : js

def render_update(proc, options)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
self.content_type = Mime::JS
self.response_body = generator.to_s
end
end end


module All add :xml do |xml, options|
extend ActiveSupport::Concern self.content_type ||= Mime::XML
self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
end


include ActionController::RenderOptions::Json add :update do |proc, options|
include ActionController::RenderOptions::Js generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
include ActionController::RenderOptions::Xml self.content_type = Mime::JS
include ActionController::RenderOptions::RJS self.response_body = generator.to_s
end end
end end
end end
14 changes: 14 additions & 0 deletions actionpack/test/controller/render_other_test.rb
Expand Up @@ -2,6 +2,11 @@
require 'controller/fake_models' require 'controller/fake_models'
require 'pathname' require 'pathname'


ActionController.add_renderer :simon do |says, options|
self.content_type = Mime::TEXT
self.response_body = "Simon says: #{says}"
end

class RenderOtherTest < ActionController::TestCase class RenderOtherTest < ActionController::TestCase
class TestController < ActionController::Base class TestController < ActionController::Base
protect_from_forgery protect_from_forgery
Expand Down Expand Up @@ -109,6 +114,10 @@ def render_alternate_default
end end
end end


def render_simon_says
render :simon => "foo"
end

private private
def default_render def default_render
if @alternate_default_render if @alternate_default_render
Expand Down Expand Up @@ -240,4 +249,9 @@ def test_should_render_with_alternate_default_render
xhr :get, :render_alternate_default xhr :get, :render_alternate_default
assert_equal %(Element.replace("foo", "partial html");), @response.body assert_equal %(Element.replace("foo", "partial html");), @response.body
end end

def test_using_custom_render_option
get :render_simon_says
assert_equal "Simon says: foo", @response.body
end
end end

0 comments on commit f9d570b

Please sign in to comment.