Skip to content

Commit edacdbf

Browse files
committed
Inline variants syntax
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 situations: 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
1 parent fbb6be5 commit edacdbf

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

actionpack/lib/action_controller/metal/mime_responds.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,12 +445,18 @@ def any(*args, &block)
445445

446446
def custom(mime_type, &block)
447447
mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
448-
@responses[mime_type] ||= block
448+
@responses[mime_type] ||= if block_given?
449+
block
450+
else
451+
VariantCollector.new
452+
end
449453
end
450454

451455
def response(variant)
452456
response = @responses.fetch(format, @responses[Mime::ALL])
453-
if response.nil? || response.arity == 0
457+
if response.is_a?(VariantCollector)
458+
response.variant(variant)
459+
elsif response.nil? || response.arity == 0
454460
response
455461
else
456462
lambda { response.call VariantFilter.new(variant) }
@@ -461,6 +467,22 @@ def negotiate_format(request)
461467
@format = request.negotiate_mime(@responses.keys)
462468
end
463469

470+
#Used for inline syntax
471+
class VariantCollector #:nodoc:
472+
def initialize
473+
@variants = {}
474+
end
475+
476+
def method_missing(name, *args, &block)
477+
@variants[name] = block if block_given?
478+
end
479+
480+
def variant(name)
481+
@variants[name.nil? ? :none : name]
482+
end
483+
end
484+
485+
#Used for nested block syntax
464486
class VariantFilter #:nodoc:
465487
def initialize(variant)
466488
@variant = variant

actionpack/test/controller/mime/respond_to_test.rb

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,22 @@ def variant_plus_none_for_format
175175
end
176176
end
177177

178+
def variant_inline_syntax
179+
respond_to do |format|
180+
format.js { render text: "js" }
181+
format.html.none { render text: "none" }
182+
format.html.phone { render text: "phone" }
183+
end
184+
end
185+
186+
def variant_inline_syntax_without_block
187+
respond_to do |format|
188+
format.js
189+
format.html.none
190+
format.html.phone
191+
end
192+
end
193+
178194
protected
179195
def set_layout
180196
case action_name
@@ -554,10 +570,31 @@ def test_multiple_variants_for_format
554570
assert_equal "tablet", @response.body
555571
end
556572

557-
558573
def test_no_variant_in_variant_setup
559574
get :variant_plus_none_for_format
560575
assert_equal "text/html", @response.content_type
561576
assert_equal "none", @response.body
562577
end
578+
579+
def test_variant_inline_syntax
580+
get :variant_inline_syntax, format: :js
581+
assert_equal "text/javascript", @response.content_type
582+
assert_equal "js", @response.body
583+
584+
get :variant_inline_syntax
585+
assert_equal "text/html", @response.content_type
586+
assert_equal "none", @response.body
587+
588+
@request.variant = :phone
589+
get :variant_inline_syntax
590+
assert_equal "text/html", @response.content_type
591+
assert_equal "phone", @response.body
592+
end
593+
594+
def test_variant_inline_syntax_without_block
595+
@request.variant = :phone
596+
get :variant_inline_syntax_without_block
597+
assert_equal "text/html", @response.content_type
598+
assert_equal "phone", @response.body
599+
end
563600
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
phone

0 commit comments

Comments
 (0)