From e429c940a30ec988a142704e88443583ef0df16d Mon Sep 17 00:00:00 2001 From: Guilherme Carreiro Date: Fri, 17 Jan 2025 11:34:39 +0100 Subject: [PATCH] Use VariableLookup instead of dot notation --- lib/liquid/standardfilters.rb | 8 ++++---- test/integration/standard_filter_test.rb | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 9da58e06..f6d91c39 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -1007,10 +1007,10 @@ module Liquid return value if !value.nil? || !property_or_keys.is_a?(String) - keys = property_or_keys.split('.') - keys.reduce(drop) do |drop, key| - drop.respond_to?(:[]) ? drop[key] : drop - end + variable_lookup = Liquid::VariableLookup.parse("drop.#{property_or_keys}") + variable_lookup.evaluate( + Liquid::Context.new("drop" => drop), + ) end def raise_property_error(property) diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index ce2a2841..4e2ccdf4 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -1337,6 +1337,30 @@ class StandardFiltersTest < Minitest::Test assert_template_result(expected_output, template, { "products" => TestDeepEnumerable.new }) end + def test_access_arrays + template = <<~LIQUID + {{- products | map: 'colors[0]["name"]' | join: ", " -}} + LIQUID + expected_output = "red, red, blue" + + assert_template_result(expected_output, template, { + "products" => [ + { "title" => { "content" => "Pro goggles" }, "colors" => [{ "name" => "red", "hex" => "#ff0000" }] }, + { "title" => { "content" => "Thermal gloves" }, "colors" => [{ "name" => "red", "hex" => "#ff0000" }] }, + { "title" => { "content" => "Alpine jacket" }, "colors" => [{ "name" => "blue", "hex" => "#0000ff" }] }, + ], + }) + end + + def test_access_lookup_with_brackets + template = <<~LIQUID + {{- products | map: 'title["content"]' | join: ', ' -}} + LIQUID + expected_output = "Pro goggles, Thermal gloves, Alpine jacket, Mountain boots, Safety helmet" + + assert_template_result(expected_output, template, { "products" => TestDeepEnumerable.new }) + end + private def with_timezone(tz)