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
Original file line number Diff line number Diff line change
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?

if collector = retrieve_collector_from_mimes(mimes, &block)
response = collector.response(request.variant)
response = collector.response
response ? response.call : render({})
end
end
Expand Down Expand Up @@ -357,7 +357,7 @@ def respond_with(*resources, &block)
if collector = retrieve_collector_from_mimes(&block)
options = resources.size == 1 ? {} : resources.extract_options!
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)
end
end
Expand Down Expand Up @@ -390,7 +390,7 @@ def collect_mimes_from_class_level #:nodoc:
# is available.
def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
mimes ||= collect_mimes_from_class_level
collector = Collector.new(mimes)
collector = Collector.new(mimes, request.variant)
block.call(collector) if block_given?
format = collector.negotiate_format(request)

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

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

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

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

def custom(mime_type, &block)
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

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

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

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

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


def test_no_variant_in_variant_setup
get :variant_plus_none_for_format
assert_equal "text/html", @response.content_type
assert_equal "none", @response.body
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

0 comments on commit 2647d2f

Please sign in to comment.