Merge pull request #1441 from Shopify/to-raw-value

Implement to_liquid_value to Liquid::Drop
This commit is contained in:
Michael Go
2021-05-27 10:21:05 -03:00
committed by GitHub
7 changed files with 100 additions and 4 deletions

View File

@@ -52,7 +52,14 @@ module Liquid
@blocks.each do |block| @blocks.each do |block|
if block.else? if block.else?
block.attachment.render_to_output_buffer(context, output) if execute_else_block block.attachment.render_to_output_buffer(context, output) if execute_else_block
elsif block.evaluate(context) next
end
result = Liquid::Utils.to_liquid_value(
block.evaluate(context)
)
if result
execute_else_block = false execute_else_block = false
block.attachment.render_to_output_buffer(context, output) block.attachment.render_to_output_buffer(context, output)
end end

View File

@@ -50,7 +50,11 @@ module Liquid
def render_to_output_buffer(context, output) def render_to_output_buffer(context, output)
@blocks.each do |block| @blocks.each do |block|
if block.evaluate(context) result = Liquid::Utils.to_liquid_value(
block.evaluate(context)
)
if result
return block.attachment.render_to_output_buffer(context, output) return block.attachment.render_to_output_buffer(context, output)
end end
end end

View File

@@ -11,13 +11,20 @@ module Liquid
def render_to_output_buffer(context, output) def render_to_output_buffer(context, output)
# First condition is interpreted backwards ( if not ) # First condition is interpreted backwards ( if not )
first_block = @blocks.first first_block = @blocks.first
unless first_block.evaluate(context) result = Liquid::Utils.to_liquid_value(
first_block.evaluate(context)
)
unless result
return first_block.attachment.render_to_output_buffer(context, output) return first_block.attachment.render_to_output_buffer(context, output)
end end
# After the first condition unless works just like if # After the first condition unless works just like if
@blocks[1..-1].each do |block| @blocks[1..-1].each do |block|
if block.evaluate(context) result = block.evaluate(context)
result = result.to_liquid_value if result.is_a?(Liquid::Drop)
if result
return block.attachment.render_to_output_buffer(context, output) return block.attachment.render_to_output_buffer(context, output)
end end
end end

View File

@@ -81,5 +81,13 @@ module Liquid
rescue ::ArgumentError rescue ::ArgumentError
nil nil
end end
def self.to_liquid_value(obj)
# Enable "obj" to represent itself as a primitive value like integer, string, or boolean
return obj.to_liquid_value if obj.respond_to?(:to_liquid_value)
# Otherwise return the object itself
obj
end
end end
end end

View File

@@ -40,6 +40,9 @@ module Liquid
@lookups.each_index do |i| @lookups.each_index do |i|
key = context.evaluate(@lookups[i]) key = context.evaluate(@lookups[i])
# Cast "key" to its liquid value to enable it to act as a primitive value
key = Liquid::Utils.to_liquid_value(key)
# If object is a hash- or array-like object we look for the # If object is a hash- or array-like object we look for the
# presence of the key and if its available we return it # presence of the key and if its available we return it
if object.respond_to?(:[]) && if object.respond_to?(:[]) &&

View File

@@ -15,6 +15,31 @@ class VariableTest < Minitest::Test
assert_template_result('foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new) assert_template_result('foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new)
end end
def test_variable_lookup_calls_to_liquid_value
assert_template_result('1', '{{ foo }}', 'foo' => IntegerDrop.new('1'))
assert_template_result('2', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => [1, 2, 3])
assert_template_result('one', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => { 1 => 'one' })
assert_template_result('Yay', '{{ foo }}', 'foo' => BooleanDrop.new(true))
assert_template_result('YAY', '{{ foo | upcase }}', 'foo' => BooleanDrop.new(true))
end
def test_if_tag_calls_to_liquid_value
assert_template_result('one', '{% if foo == 1 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
assert_template_result('true', '{% if foo == true %}true{% endif %}', 'foo' => BooleanDrop.new(true))
assert_template_result('true', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(true))
assert_template_result('', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(false))
assert_template_result('', '{% if foo == true %}True{% endif %}', 'foo' => BooleanDrop.new(false))
end
def test_unless_tag_calls_to_liquid_value
assert_template_result('', '{% unless foo %}true{% endunless %}', 'foo' => BooleanDrop.new(true))
end
def test_case_tag_calls_to_liquid_value
assert_template_result('One', '{% case foo %}{% when 1 %}One{% endcase %}', 'foo' => IntegerDrop.new('1'))
end
def test_simple_with_whitespaces def test_simple_with_whitespaces
template = Template.parse(%( {{ test }} )) template = Template.parse(%( {{ test }} ))
assert_equal(' worked ', template.render!('test' => 'worked')) assert_equal(' worked ', template.render!('test' => 'worked'))
@@ -104,4 +129,8 @@ class VariableTest < Minitest::Test
def test_dynamic_find_var def test_dynamic_find_var
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar') assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
end end
def test_raw_value_variable
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
end
end end

View File

@@ -119,6 +119,44 @@ class ThingWithToLiquid
end end
end end
class IntegerDrop < Liquid::Drop
def initialize(value)
super()
@value = value.to_i
end
def ==(other)
@value == other
end
def to_s
@value.to_s
end
def to_liquid_value
@value
end
end
class BooleanDrop < Liquid::Drop
def initialize(value)
super()
@value = value
end
def ==(other)
@value == other
end
def to_liquid_value
@value
end
def to_s
@value ? "Yay" : "Nay"
end
end
class ErrorDrop < Liquid::Drop class ErrorDrop < Liquid::Drop
def standard_error def standard_error
raise Liquid::StandardError, 'standard error' raise Liquid::StandardError, 'standard error'