Skip to content

Commit

Permalink
Inline variants syntax
Browse files Browse the repository at this point in the history
In most cases, when setting variant specific code, you're not sharing any code
within format.

Inline syntax can vastly simplify defining variants in those sitiations:

  respond_to do |format|
    format.js { render "trash" }
    format.html do |variant|
      variant.phone { redirect_to progress_path }
      variant.none  { render "trash" }
    end
  end
`
Becomes:

  respond_to do |format|
    format.js         { render "trash" }
    format.html.phone { redirect_to progress_path }
    format.html.none  { render "trash" }
  end
  • Loading branch information
lukaszx0 committed Dec 8, 2013
1 parent 9b8c0ff commit 2647d2f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
22 changes: 14 additions & 8 deletions actionpack/lib/action_controller/metal/mime_responds.rb
Expand Up @@ -215,7 +215,7 @@ def respond_to(*mimes, &block)
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given? raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?


if collector = retrieve_collector_from_mimes(mimes, &block) if collector = retrieve_collector_from_mimes(mimes, &block)
response = collector.response(request.variant) response = collector.response
response ? response.call : render({}) response ? response.call : render({})
end end
end end
Expand Down Expand Up @@ -357,7 +357,7 @@ def respond_with(*resources, &block)
if collector = retrieve_collector_from_mimes(&block) if collector = retrieve_collector_from_mimes(&block)
options = resources.size == 1 ? {} : resources.extract_options! options = resources.size == 1 ? {} : resources.extract_options!
options = options.clone options = options.clone
options[:default_response] = collector.response(request.variant) options[:default_response] = collector.response
(options.delete(:responder) || self.class.responder).call(self, resources, options) (options.delete(:responder) || self.class.responder).call(self, resources, options)
end end
end end
Expand Down Expand Up @@ -390,7 +390,7 @@ def collect_mimes_from_class_level #:nodoc:
# is available. # is available.
def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc: def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
mimes ||= collect_mimes_from_class_level mimes ||= collect_mimes_from_class_level
collector = Collector.new(mimes) collector = Collector.new(mimes, request.variant)
block.call(collector) if block_given? block.call(collector) if block_given?
format = collector.negotiate_format(request) format = collector.negotiate_format(request)


Expand Down Expand Up @@ -428,8 +428,10 @@ class Collector
include AbstractController::Collector include AbstractController::Collector
attr_accessor :format attr_accessor :format


def initialize(mimes) def initialize(mimes, variant = nil)
@responses = {} @responses = {}
@variant = variant

mimes.each { |mime| @responses["Mime::#{mime.upcase}".constantize] = nil } mimes.each { |mime| @responses["Mime::#{mime.upcase}".constantize] = nil }
end end


Expand All @@ -444,15 +446,19 @@ def any(*args, &block)


def custom(mime_type, &block) def custom(mime_type, &block)
mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type) mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
@responses[mime_type] ||= block @responses[mime_type] ||= if block_given?
block
else
VariantFilter.new(@variant)
end
end end


def response(variant) def response
response = @responses.fetch(format, @responses[Mime::ALL]) response = @responses.fetch(format, @responses[Mime::ALL])
if response.nil? || response.arity == 0 if response.is_a?(VariantFilter) || response.nil? || response.arity == 0
response response
else else
lambda { response.call VariantFilter.new(variant) } lambda { response.call VariantFilter.new(@variant) }
end end
end end


Expand Down
14 changes: 13 additions & 1 deletion actionpack/test/controller/mime/respond_to_test.rb
Expand Up @@ -175,6 +175,12 @@ def variant_plus_none_for_format
end end
end end


def variant_inline_syntax
respond_to do |format|
format.html.phone { render text: "phone" }
end
end

protected protected
def set_layout def set_layout
case action_name case action_name
Expand Down Expand Up @@ -554,10 +560,16 @@ def test_multiple_variants_for_format
assert_equal "tablet", @response.body assert_equal "tablet", @response.body
end end



def test_no_variant_in_variant_setup def test_no_variant_in_variant_setup
get :variant_plus_none_for_format get :variant_plus_none_for_format
assert_equal "text/html", @response.content_type assert_equal "text/html", @response.content_type
assert_equal "none", @response.body assert_equal "none", @response.body
end end

def test_variant_inline_syntax
@request.variant = :phone
get :variant_inline_syntax
assert_equal "text/html", @response.content_type
assert_equal "phone", @response.body
end
end end

0 comments on commit 2647d2f

Please sign in to comment.