mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-20 19:30:47 -07:00
Centralizing to_liquid
This commit is contained in:
+29
-11
@@ -187,16 +187,11 @@ module Liquid
|
|||||||
# path and find_index() is optimized in MRI to reduce object allocation
|
# path and find_index() is optimized in MRI to reduce object allocation
|
||||||
index = @scopes.find_index { |s| s.key?(key) }
|
index = @scopes.find_index { |s| s.key?(key) }
|
||||||
|
|
||||||
variable = if index
|
if index
|
||||||
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)
|
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)
|
||||||
else
|
else
|
||||||
try_variable_find_in_environments(key, raise_on_not_found: raise_on_not_found)
|
try_variable_find_in_environments(key, raise_on_not_found: raise_on_not_found)
|
||||||
end
|
end
|
||||||
|
|
||||||
variable = variable.to_liquid
|
|
||||||
variable.context = self if variable.respond_to?(:context=)
|
|
||||||
|
|
||||||
variable
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def lookup_and_evaluate(obj, key, raise_on_not_found: true)
|
def lookup_and_evaluate(obj, key, raise_on_not_found: true)
|
||||||
@@ -204,13 +199,17 @@ module Liquid
|
|||||||
raise Liquid::UndefinedVariable, "undefined variable #{key}"
|
raise Liquid::UndefinedVariable, "undefined variable #{key}"
|
||||||
end
|
end
|
||||||
|
|
||||||
value = obj[key]
|
original = obj[key]
|
||||||
|
|
||||||
if value.is_a?(Proc) && obj.respond_to?(:[]=)
|
value = contextualize(original)
|
||||||
obj[key] = value.arity == 0 ? value.call : value.call(self)
|
|
||||||
else
|
# TODO: I'd like to fold this under the liquid sanitization
|
||||||
value
|
# Original text from VariableLookup: if its a proc we will replace the entry with the proc
|
||||||
|
if original.is_a?(Proc) && obj.respond_to?(:[]=)
|
||||||
|
obj[key] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_disabled_tags(tag_names)
|
def with_disabled_tags(tag_names)
|
||||||
@@ -228,6 +227,25 @@ module Liquid
|
|||||||
@disabled_tags.fetch(tag_name, 0) > 0
|
@disabled_tags.fetch(tag_name, 0) > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Let's think as to how name this.
|
||||||
|
# The strait forward name is to use "to_liquid(object)" but I do not think this fully captures what it do.
|
||||||
|
# Also, "to_liquid" is already used anywhere and is more of a generic name at this point.
|
||||||
|
# When we call "to_liquid" we are "sanitizing" the input?
|
||||||
|
# We also want to "bind" the object to the current rendering "@context".
|
||||||
|
def contextualize(object)
|
||||||
|
if object.is_a?(Proc)
|
||||||
|
object = object.arity == 0 ? object.call : object.call(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
object = object.to_liquid
|
||||||
|
|
||||||
|
# TODO: ideally all contextualized object would define "context=" even if they end up noop-ing it.
|
||||||
|
# For now this is not really a pressing issue to deal with.
|
||||||
|
object.context = self if object.respond_to?(:context=)
|
||||||
|
|
||||||
|
object
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_writer :base_scope_depth, :warnings, :errors, :strainer, :filters, :disabled_tags
|
attr_writer :base_scope_depth, :warnings, :errors, :strainer, :filters, :disabled_tags
|
||||||
|
|||||||
@@ -582,8 +582,11 @@ module Liquid
|
|||||||
|
|
||||||
def each
|
def each
|
||||||
@input.each do |e|
|
@input.each do |e|
|
||||||
e.context = @context if e.respond_to?(:context=)
|
# TODO: this conversion should occur outside the filter.
|
||||||
yield(e.respond_to?(:to_liquid) ? e.to_liquid : e)
|
# This is a change I desire to make but might not make the cut for the current change at hand.
|
||||||
|
e = @context.contextualize(e)
|
||||||
|
|
||||||
|
yield(e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -49,15 +49,17 @@ module Liquid
|
|||||||
((object.respond_to?(:key?) && object.key?(key)) ||
|
((object.respond_to?(:key?) && object.key?(key)) ||
|
||||||
(object.respond_to?(:fetch) && key.is_a?(Integer)))
|
(object.respond_to?(:fetch) && key.is_a?(Integer)))
|
||||||
|
|
||||||
# if its a proc we will replace the entry with the proc
|
object = context.lookup_and_evaluate(object, key)
|
||||||
res = context.lookup_and_evaluate(object, key)
|
|
||||||
object = res.to_liquid
|
|
||||||
|
|
||||||
# Some special cases. If the part wasn't in square brackets and
|
# Some special cases. If the part wasn't in square brackets and
|
||||||
# no key with the same name was found we interpret following calls
|
# no key with the same name was found we interpret following calls
|
||||||
# as commands and call them on the current object
|
# as commands and call them on the current object
|
||||||
elsif @command_flags & (1 << i) != 0 && object.respond_to?(key)
|
elsif @command_flags & (1 << i) != 0 && object.respond_to?(key)
|
||||||
object = object.send(key).to_liquid
|
|
||||||
|
# TODO: These do not go through lookup_and_evaluate.
|
||||||
|
# Let's see if we can move the conversion back to Context
|
||||||
|
object = object.send(key)
|
||||||
|
object = context.contextualize(object)
|
||||||
|
|
||||||
# No key was present with the desired value and it wasn't one of the directly supported
|
# No key was present with the desired value and it wasn't one of the directly supported
|
||||||
# keywords either. The only thing we got left is to return nil or
|
# keywords either. The only thing we got left is to return nil or
|
||||||
|
|||||||
@@ -861,7 +861,7 @@ class StandardFiltersTest < Minitest::Test
|
|||||||
{ foo: "bar" },
|
{ foo: "bar" },
|
||||||
[{ "foo" => "bar" }, { "foo" => 123 }, { "foo" => nil }, { "foo" => true }, { "foo" => ["foo", "bar"] }],
|
[{ "foo" => "bar" }, { "foo" => 123 }, { "foo" => nil }, { "foo" => true }, { "foo" => ["foo", "bar"] }],
|
||||||
{ 1 => "bar" },
|
{ 1 => "bar" },
|
||||||
["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
|
["foo", 123, nil, true, false, test_drop, test_enum, ["foo"], { foo: "bar" }],
|
||||||
]
|
]
|
||||||
StandardFilters.public_instance_methods(false).each do |method|
|
StandardFilters.public_instance_methods(false).each do |method|
|
||||||
arg_count = @filters.method(method).arity
|
arg_count = @filters.method(method).arity
|
||||||
|
|||||||
Reference in New Issue
Block a user