Skip to content

Commit

Permalink
update variable's context before invoking its to_liquid
Browse files Browse the repository at this point in the history
  • Loading branch information
ggmichaelgo committed Jan 25, 2024
1 parent 9b38a15 commit 47a04ff
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/liquid/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,14 @@ def find_variable(key, raise_on_not_found: true)
try_variable_find_in_environments(key, raise_on_not_found: raise_on_not_found)
end

variable = variable.to_liquid
# update variable's context before invoking #to_liquid
variable.context = self if variable.respond_to?(:context=)

variable
liquid_variable = variable.to_liquid

liquid_variable.context = self if variable != liquid_variable && liquid_variable.respond_to?(:context=)

liquid_variable
end

def lookup_and_evaluate(obj, key, raise_on_not_found: true)
Expand Down
37 changes: 37 additions & 0 deletions test/integration/context_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@ def to_liquid
end
end

class ProductsDrop < Liquid::Drop
def initialize(products)
@products = products
end

def size
@products.size
end

def to_liquid
if @context && @context["forloop"]
@products.first(@context["forloop"].length)
else
@products
end
end
end

class CategoryDrop < Liquid::Drop
attr_accessor :category, :context

Expand Down Expand Up @@ -635,6 +653,25 @@ def test_context_always_uses_static_registers
assert_equal(:my_value, c.registers[:my_register])
end

def test_variable_to_liquid_returns_contextual_drop
context = {
"products" => ProductsDrop.new(["A", "B", "C", "D", "E"]),
}

template = Liquid::Template.parse(<<~LIQUID)
{%- for i in (1..3) -%}
for_loop_products_count: {{ products | size }}
{% endfor %}
unscoped_products_count: {{ products | size }}
LIQUID

result = template.render(context)

assert_includes(result, "for_loop_products_count: 3")
assert_includes(result, "unscoped_products_count: 5")
end

private

def assert_no_object_allocations
Expand Down

0 comments on commit 47a04ff

Please sign in to comment.